mirror of
https://github.com/bergercookie/asm-lsp.git
synced 2025-12-23 12:26:44 +00:00
6502 lines
219 KiB
HTML
Vendored
6502 lines
219 KiB
HTML
Vendored
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<LINK REL="stylesheet" TYPE="text/css" HREF="doc.css">
|
|
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.82">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<TITLE>ca65 Users Guide</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<H1>ca65 Users Guide</H1>
|
|
|
|
<H2>
|
|
<A HREF="mailto:uz@cc65.org">Ullrich von Bassewitz</A>,<BR>
|
|
<A HREF="mailto:greg.king5@verizon.net">Greg King</A></H2>
|
|
<HR>
|
|
<EM>ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is
|
|
used as a companion assembler for the cc65 crosscompiler, but it may also be
|
|
used as a standalone product.</EM>
|
|
<HR>
|
|
<P>
|
|
<H2><A NAME="toc1">1.</A> <A HREF="ca65.html#s1">Overview</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc1.1">1.1</A> <A HREF="ca65.html#ss1.1">Design criteria</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc2">2.</A> <A HREF="ca65.html#s2">Usage</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc2.1">2.1</A> <A HREF="ca65.html#ss2.1">Command line option overview</A>
|
|
<LI><A NAME="toc2.2">2.2</A> <A HREF="ca65.html#ss2.2">Command line options in detail</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc3">3.</A> <A HREF="ca65.html#s3">Search paths</A></H2>
|
|
|
|
<P>
|
|
<H2><A NAME="toc4">4.</A> <A HREF="ca65.html#s4">Input format</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc4.1">4.1</A> <A HREF="ca65.html#ss4.1">Assembler syntax</A>
|
|
<LI><A NAME="toc4.2">4.2</A> <A HREF="ca65.html#ss4.2">65816 mode</A>
|
|
<LI><A NAME="toc4.3">4.3</A> <A HREF="ca65.html#ss4.3">6502X mode</A>
|
|
<LI><A NAME="toc4.4">4.4</A> <A HREF="ca65.html#ss4.4">4510 mode</A>
|
|
<LI><A NAME="toc4.5">4.5</A> <A HREF="ca65.html#ss4.5">sweet16 mode</A>
|
|
<LI><A NAME="toc4.6">4.6</A> <A HREF="ca65.html#ss4.6">Number format</A>
|
|
<LI><A NAME="toc4.7">4.7</A> <A HREF="ca65.html#ss4.7">Conditional assembly</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc5">5.</A> <A HREF="ca65.html#s5">Expressions</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc5.1">5.1</A> <A HREF="ca65.html#ss5.1">Expression evaluation</A>
|
|
<LI><A NAME="toc5.2">5.2</A> <A HREF="ca65.html#ss5.2">Size of an expression result</A>
|
|
<LI><A NAME="toc5.3">5.3</A> <A HREF="ca65.html#ss5.3">Boolean expressions</A>
|
|
<LI><A NAME="toc5.4">5.4</A> <A HREF="ca65.html#ss5.4">Constant expressions</A>
|
|
<LI><A NAME="toc5.5">5.5</A> <A HREF="ca65.html#ss5.5">Available operators</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc6">6.</A> <A HREF="ca65.html#s6">Symbols and labels</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc6.1">6.1</A> <A HREF="ca65.html#ss6.1">Numeric constants</A>
|
|
<LI><A NAME="toc6.2">6.2</A> <A HREF="ca65.html#ss6.2">Numeric variables</A>
|
|
<LI><A NAME="toc6.3">6.3</A> <A HREF="ca65.html#ss6.3">Standard labels</A>
|
|
<LI><A NAME="toc6.4">6.4</A> <A HREF="ca65.html#ss6.4">Local labels and symbols</A>
|
|
<LI><A NAME="toc6.5">6.5</A> <A HREF="ca65.html#ss6.5">Cheap local labels</A>
|
|
<LI><A NAME="toc6.6">6.6</A> <A HREF="ca65.html#ss6.6">Unnamed labels</A>
|
|
<LI><A NAME="toc6.7">6.7</A> <A HREF="ca65.html#ss6.7">Using macros to define labels and constants</A>
|
|
<LI><A NAME="toc6.8">6.8</A> <A HREF="ca65.html#ss6.8">Symbols and <CODE>.DEBUGINFO</CODE></A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc7">7.</A> <A HREF="ca65.html#s7">Scopes</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc7.1">7.1</A> <A HREF="ca65.html#ss7.1">Global scope</A>
|
|
<LI><A NAME="toc7.2">7.2</A> <A HREF="ca65.html#ss7.2">Cheap locals</A>
|
|
<LI><A NAME="toc7.3">7.3</A> <A HREF="ca65.html#ss7.3">Generic nested scopes</A>
|
|
<LI><A NAME="toc7.4">7.4</A> <A HREF="ca65.html#ss7.4">Nested procedures</A>
|
|
<LI><A NAME="toc7.5">7.5</A> <A HREF="ca65.html#ss7.5">Structs, unions and enums</A>
|
|
<LI><A NAME="toc7.6">7.6</A> <A HREF="ca65.html#ss7.6">Explicit scope specification</A>
|
|
<LI><A NAME="toc7.7">7.7</A> <A HREF="ca65.html#ss7.7">Scope search order</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc8">8.</A> <A HREF="ca65.html#s8">Address sizes and memory models</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc8.1">8.1</A> <A HREF="ca65.html#ss8.1">Address sizes</A>
|
|
<LI><A NAME="toc8.2">8.2</A> <A HREF="ca65.html#ss8.2">Address sizes of segments</A>
|
|
<LI><A NAME="toc8.3">8.3</A> <A HREF="ca65.html#ss8.3">Address sizes of symbols</A>
|
|
<LI><A NAME="toc8.4">8.4</A> <A HREF="ca65.html#ss8.4">Memory models</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc9">9.</A> <A HREF="ca65.html#s9">Pseudo variables</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc9.1">9.1</A> <A HREF="ca65.html#ss9.1"><CODE>*</CODE></A>
|
|
<LI><A NAME="toc9.2">9.2</A> <A HREF="ca65.html#ss9.2"><CODE>.ASIZE</CODE></A>
|
|
<LI><A NAME="toc9.3">9.3</A> <A HREF="ca65.html#ss9.3"><CODE>.CPU</CODE></A>
|
|
<LI><A NAME="toc9.4">9.4</A> <A HREF="ca65.html#ss9.4"><CODE>.ISIZE</CODE></A>
|
|
<LI><A NAME="toc9.5">9.5</A> <A HREF="ca65.html#ss9.5"><CODE>.PARAMCOUNT</CODE></A>
|
|
<LI><A NAME="toc9.6">9.6</A> <A HREF="ca65.html#ss9.6"><CODE>.TIME</CODE></A>
|
|
<LI><A NAME="toc9.7">9.7</A> <A HREF="ca65.html#ss9.7"><CODE>.VERSION</CODE></A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc10">10.</A> <A HREF="ca65.html#s10">Pseudo functions</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc10.1">10.1</A> <A HREF="ca65.html#ss10.1"><CODE>.ADDRSIZE</CODE></A>
|
|
<LI><A NAME="toc10.2">10.2</A> <A HREF="ca65.html#ss10.2"><CODE>.BANK</CODE></A>
|
|
<LI><A NAME="toc10.3">10.3</A> <A HREF="ca65.html#ss10.3"><CODE>.BANKBYTE</CODE></A>
|
|
<LI><A NAME="toc10.4">10.4</A> <A HREF="ca65.html#ss10.4"><CODE>.BLANK</CODE></A>
|
|
<LI><A NAME="toc10.5">10.5</A> <A HREF="ca65.html#ss10.5"><CODE>.CONCAT</CODE></A>
|
|
<LI><A NAME="toc10.6">10.6</A> <A HREF="ca65.html#ss10.6"><CODE>.CONST</CODE></A>
|
|
<LI><A NAME="toc10.7">10.7</A> <A HREF="ca65.html#ss10.7"><CODE>.DEF, .DEFINED</CODE></A>
|
|
<LI><A NAME="toc10.8">10.8</A> <A HREF="ca65.html#ss10.8"><CODE>.DEFINEDMACRO</CODE></A>
|
|
<LI><A NAME="toc10.9">10.9</A> <A HREF="ca65.html#ss10.9"><CODE>.HIBYTE</CODE></A>
|
|
<LI><A NAME="toc10.10">10.10</A> <A HREF="ca65.html#ss10.10"><CODE>.HIWORD</CODE></A>
|
|
<LI><A NAME="toc10.11">10.11</A> <A HREF="ca65.html#ss10.11"><CODE>.IDENT</CODE></A>
|
|
<LI><A NAME="toc10.12">10.12</A> <A HREF="ca65.html#ss10.12"><CODE>.ISMNEM, .ISMNEMONIC</CODE></A>
|
|
<LI><A NAME="toc10.13">10.13</A> <A HREF="ca65.html#ss10.13"><CODE>.LEFT</CODE></A>
|
|
<LI><A NAME="toc10.14">10.14</A> <A HREF="ca65.html#ss10.14"><CODE>.LOBYTE</CODE></A>
|
|
<LI><A NAME="toc10.15">10.15</A> <A HREF="ca65.html#ss10.15"><CODE>.LOWORD</CODE></A>
|
|
<LI><A NAME="toc10.16">10.16</A> <A HREF="ca65.html#ss10.16"><CODE>.MATCH</CODE></A>
|
|
<LI><A NAME="toc10.17">10.17</A> <A HREF="ca65.html#ss10.17"><CODE>.MAX</CODE></A>
|
|
<LI><A NAME="toc10.18">10.18</A> <A HREF="ca65.html#ss10.18"><CODE>.MID</CODE></A>
|
|
<LI><A NAME="toc10.19">10.19</A> <A HREF="ca65.html#ss10.19"><CODE>.MIN</CODE></A>
|
|
<LI><A NAME="toc10.20">10.20</A> <A HREF="ca65.html#ss10.20"><CODE>.REF, .REFERENCED</CODE></A>
|
|
<LI><A NAME="toc10.21">10.21</A> <A HREF="ca65.html#ss10.21"><CODE>.RIGHT</CODE></A>
|
|
<LI><A NAME="toc10.22">10.22</A> <A HREF="ca65.html#ss10.22"><CODE>.SIZEOF</CODE></A>
|
|
<LI><A NAME="toc10.23">10.23</A> <A HREF="ca65.html#ss10.23"><CODE>.SPRINTF</CODE></A>
|
|
<LI><A NAME="toc10.24">10.24</A> <A HREF="ca65.html#ss10.24"><CODE>.STRAT</CODE></A>
|
|
<LI><A NAME="toc10.25">10.25</A> <A HREF="ca65.html#ss10.25"><CODE>.STRING</CODE></A>
|
|
<LI><A NAME="toc10.26">10.26</A> <A HREF="ca65.html#ss10.26"><CODE>.STRLEN</CODE></A>
|
|
<LI><A NAME="toc10.27">10.27</A> <A HREF="ca65.html#ss10.27"><CODE>.TCOUNT</CODE></A>
|
|
<LI><A NAME="toc10.28">10.28</A> <A HREF="ca65.html#ss10.28"><CODE>.XMATCH</CODE></A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc11">11.</A> <A HREF="ca65.html#s11">Control commands</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc11.1">11.1</A> <A HREF="ca65.html#ss11.1"><CODE>.A16</CODE></A>
|
|
<LI><A NAME="toc11.2">11.2</A> <A HREF="ca65.html#ss11.2"><CODE>.A8</CODE></A>
|
|
<LI><A NAME="toc11.3">11.3</A> <A HREF="ca65.html#ss11.3"><CODE>.ADDR</CODE></A>
|
|
<LI><A NAME="toc11.4">11.4</A> <A HREF="ca65.html#ss11.4"><CODE>.ALIGN</CODE></A>
|
|
<LI><A NAME="toc11.5">11.5</A> <A HREF="ca65.html#ss11.5"><CODE>.ASCIIZ</CODE></A>
|
|
<LI><A NAME="toc11.6">11.6</A> <A HREF="ca65.html#ss11.6"><CODE>.ASSERT</CODE></A>
|
|
<LI><A NAME="toc11.7">11.7</A> <A HREF="ca65.html#ss11.7"><CODE>.AUTOIMPORT</CODE></A>
|
|
<LI><A NAME="toc11.8">11.8</A> <A HREF="ca65.html#ss11.8"><CODE>.BANKBYTES</CODE></A>
|
|
<LI><A NAME="toc11.9">11.9</A> <A HREF="ca65.html#ss11.9"><CODE>.BSS</CODE></A>
|
|
<LI><A NAME="toc11.10">11.10</A> <A HREF="ca65.html#ss11.10"><CODE>.BYT, .BYTE</CODE></A>
|
|
<LI><A NAME="toc11.11">11.11</A> <A HREF="ca65.html#ss11.11"><CODE>.CASE</CODE></A>
|
|
<LI><A NAME="toc11.12">11.12</A> <A HREF="ca65.html#ss11.12"><CODE>.CHARMAP</CODE></A>
|
|
<LI><A NAME="toc11.13">11.13</A> <A HREF="ca65.html#ss11.13"><CODE>.CODE</CODE></A>
|
|
<LI><A NAME="toc11.14">11.14</A> <A HREF="ca65.html#ss11.14"><CODE>.CONDES</CODE></A>
|
|
<LI><A NAME="toc11.15">11.15</A> <A HREF="ca65.html#ss11.15"><CODE>.CONSTRUCTOR</CODE></A>
|
|
<LI><A NAME="toc11.16">11.16</A> <A HREF="ca65.html#ss11.16"><CODE>.DATA</CODE></A>
|
|
<LI><A NAME="toc11.17">11.17</A> <A HREF="ca65.html#ss11.17"><CODE>.DBYT</CODE></A>
|
|
<LI><A NAME="toc11.18">11.18</A> <A HREF="ca65.html#ss11.18"><CODE>.DEBUGINFO</CODE></A>
|
|
<LI><A NAME="toc11.19">11.19</A> <A HREF="ca65.html#ss11.19"><CODE>.DEFINE</CODE></A>
|
|
<LI><A NAME="toc11.20">11.20</A> <A HREF="ca65.html#ss11.20"><CODE>.DELMAC, .DELMACRO</CODE></A>
|
|
<LI><A NAME="toc11.21">11.21</A> <A HREF="ca65.html#ss11.21"><CODE>.DESTRUCTOR</CODE></A>
|
|
<LI><A NAME="toc11.22">11.22</A> <A HREF="ca65.html#ss11.22"><CODE>.DWORD</CODE></A>
|
|
<LI><A NAME="toc11.23">11.23</A> <A HREF="ca65.html#ss11.23"><CODE>.ELSE</CODE></A>
|
|
<LI><A NAME="toc11.24">11.24</A> <A HREF="ca65.html#ss11.24"><CODE>.ELSEIF</CODE></A>
|
|
<LI><A NAME="toc11.25">11.25</A> <A HREF="ca65.html#ss11.25"><CODE>.END</CODE></A>
|
|
<LI><A NAME="toc11.26">11.26</A> <A HREF="ca65.html#ss11.26"><CODE>.ENDENUM</CODE></A>
|
|
<LI><A NAME="toc11.27">11.27</A> <A HREF="ca65.html#ss11.27"><CODE>.ENDIF</CODE></A>
|
|
<LI><A NAME="toc11.28">11.28</A> <A HREF="ca65.html#ss11.28"><CODE>.ENDMAC, .ENDMACRO</CODE></A>
|
|
<LI><A NAME="toc11.29">11.29</A> <A HREF="ca65.html#ss11.29"><CODE>.ENDPROC</CODE></A>
|
|
<LI><A NAME="toc11.30">11.30</A> <A HREF="ca65.html#ss11.30"><CODE>.ENDREP, .ENDREPEAT</CODE></A>
|
|
<LI><A NAME="toc11.31">11.31</A> <A HREF="ca65.html#ss11.31"><CODE>.ENDSCOPE</CODE></A>
|
|
<LI><A NAME="toc11.32">11.32</A> <A HREF="ca65.html#ss11.32"><CODE>.ENDSTRUCT</CODE></A>
|
|
<LI><A NAME="toc11.33">11.33</A> <A HREF="ca65.html#ss11.33"><CODE>.ENDUNION</CODE></A>
|
|
<LI><A NAME="toc11.34">11.34</A> <A HREF="ca65.html#ss11.34"><CODE>.ENUM</CODE></A>
|
|
<LI><A NAME="toc11.35">11.35</A> <A HREF="ca65.html#ss11.35"><CODE>.ERROR</CODE></A>
|
|
<LI><A NAME="toc11.36">11.36</A> <A HREF="ca65.html#ss11.36"><CODE>.EXITMAC, .EXITMACRO</CODE></A>
|
|
<LI><A NAME="toc11.37">11.37</A> <A HREF="ca65.html#ss11.37"><CODE>.EXPORT</CODE></A>
|
|
<LI><A NAME="toc11.38">11.38</A> <A HREF="ca65.html#ss11.38"><CODE>.EXPORTZP</CODE></A>
|
|
<LI><A NAME="toc11.39">11.39</A> <A HREF="ca65.html#ss11.39"><CODE>.FARADDR</CODE></A>
|
|
<LI><A NAME="toc11.40">11.40</A> <A HREF="ca65.html#ss11.40"><CODE>.FATAL</CODE></A>
|
|
<LI><A NAME="toc11.41">11.41</A> <A HREF="ca65.html#ss11.41"><CODE>.FEATURE</CODE></A>
|
|
<LI><A NAME="toc11.42">11.42</A> <A HREF="ca65.html#ss11.42"><CODE>.FILEOPT, .FOPT</CODE></A>
|
|
<LI><A NAME="toc11.43">11.43</A> <A HREF="ca65.html#ss11.43"><CODE>.FORCEIMPORT</CODE></A>
|
|
<LI><A NAME="toc11.44">11.44</A> <A HREF="ca65.html#ss11.44"><CODE>.GLOBAL</CODE></A>
|
|
<LI><A NAME="toc11.45">11.45</A> <A HREF="ca65.html#ss11.45"><CODE>.GLOBALZP</CODE></A>
|
|
<LI><A NAME="toc11.46">11.46</A> <A HREF="ca65.html#ss11.46"><CODE>.HIBYTES</CODE></A>
|
|
<LI><A NAME="toc11.47">11.47</A> <A HREF="ca65.html#ss11.47"><CODE>.I16</CODE></A>
|
|
<LI><A NAME="toc11.48">11.48</A> <A HREF="ca65.html#ss11.48"><CODE>.I8</CODE></A>
|
|
<LI><A NAME="toc11.49">11.49</A> <A HREF="ca65.html#ss11.49"><CODE>.IF</CODE></A>
|
|
<LI><A NAME="toc11.50">11.50</A> <A HREF="ca65.html#ss11.50"><CODE>.IFBLANK</CODE></A>
|
|
<LI><A NAME="toc11.51">11.51</A> <A HREF="ca65.html#ss11.51"><CODE>.IFCONST</CODE></A>
|
|
<LI><A NAME="toc11.52">11.52</A> <A HREF="ca65.html#ss11.52"><CODE>.IFDEF</CODE></A>
|
|
<LI><A NAME="toc11.53">11.53</A> <A HREF="ca65.html#ss11.53"><CODE>.IFNBLANK</CODE></A>
|
|
<LI><A NAME="toc11.54">11.54</A> <A HREF="ca65.html#ss11.54"><CODE>.IFNDEF</CODE></A>
|
|
<LI><A NAME="toc11.55">11.55</A> <A HREF="ca65.html#ss11.55"><CODE>.IFNREF</CODE></A>
|
|
<LI><A NAME="toc11.56">11.56</A> <A HREF="ca65.html#ss11.56"><CODE>.IFP02</CODE></A>
|
|
<LI><A NAME="toc11.57">11.57</A> <A HREF="ca65.html#ss11.57"><CODE>.IFP4510</CODE></A>
|
|
<LI><A NAME="toc11.58">11.58</A> <A HREF="ca65.html#ss11.58"><CODE>.IFP816</CODE></A>
|
|
<LI><A NAME="toc11.59">11.59</A> <A HREF="ca65.html#ss11.59"><CODE>.IFPC02</CODE></A>
|
|
<LI><A NAME="toc11.60">11.60</A> <A HREF="ca65.html#ss11.60"><CODE>.IFPDTV</CODE></A>
|
|
<LI><A NAME="toc11.61">11.61</A> <A HREF="ca65.html#ss11.61"><CODE>.IFPSC02</CODE></A>
|
|
<LI><A NAME="toc11.62">11.62</A> <A HREF="ca65.html#ss11.62"><CODE>.IFREF</CODE></A>
|
|
<LI><A NAME="toc11.63">11.63</A> <A HREF="ca65.html#ss11.63"><CODE>.IMPORT</CODE></A>
|
|
<LI><A NAME="toc11.64">11.64</A> <A HREF="ca65.html#ss11.64"><CODE>.IMPORTZP</CODE></A>
|
|
<LI><A NAME="toc11.65">11.65</A> <A HREF="ca65.html#ss11.65"><CODE>.INCBIN</CODE></A>
|
|
<LI><A NAME="toc11.66">11.66</A> <A HREF="ca65.html#ss11.66"><CODE>.INCLUDE</CODE></A>
|
|
<LI><A NAME="toc11.67">11.67</A> <A HREF="ca65.html#ss11.67"><CODE>.INTERRUPTOR</CODE></A>
|
|
<LI><A NAME="toc11.68">11.68</A> <A HREF="ca65.html#ss11.68"><CODE>.LIST</CODE></A>
|
|
<LI><A NAME="toc11.69">11.69</A> <A HREF="ca65.html#ss11.69"><CODE>.LISTBYTES</CODE></A>
|
|
<LI><A NAME="toc11.70">11.70</A> <A HREF="ca65.html#ss11.70"><CODE>.LITERAL</CODE></A>
|
|
<LI><A NAME="toc11.71">11.71</A> <A HREF="ca65.html#ss11.71"><CODE>.LOBYTES</CODE></A>
|
|
<LI><A NAME="toc11.72">11.72</A> <A HREF="ca65.html#ss11.72"><CODE>.LOCAL</CODE></A>
|
|
<LI><A NAME="toc11.73">11.73</A> <A HREF="ca65.html#ss11.73"><CODE>.LOCALCHAR</CODE></A>
|
|
<LI><A NAME="toc11.74">11.74</A> <A HREF="ca65.html#ss11.74"><CODE>.MACPACK</CODE></A>
|
|
<LI><A NAME="toc11.75">11.75</A> <A HREF="ca65.html#ss11.75"><CODE>.MAC, .MACRO</CODE></A>
|
|
<LI><A NAME="toc11.76">11.76</A> <A HREF="ca65.html#ss11.76"><CODE>.ORG</CODE></A>
|
|
<LI><A NAME="toc11.77">11.77</A> <A HREF="ca65.html#ss11.77"><CODE>.OUT</CODE></A>
|
|
<LI><A NAME="toc11.78">11.78</A> <A HREF="ca65.html#ss11.78"><CODE>.P02</CODE></A>
|
|
<LI><A NAME="toc11.79">11.79</A> <A HREF="ca65.html#ss11.79"><CODE>.P4510</CODE></A>
|
|
<LI><A NAME="toc11.80">11.80</A> <A HREF="ca65.html#ss11.80"><CODE>.P816</CODE></A>
|
|
<LI><A NAME="toc11.81">11.81</A> <A HREF="ca65.html#ss11.81"><CODE>.PAGELEN, .PAGELENGTH</CODE></A>
|
|
<LI><A NAME="toc11.82">11.82</A> <A HREF="ca65.html#ss11.82"><CODE>.PC02</CODE></A>
|
|
<LI><A NAME="toc11.83">11.83</A> <A HREF="ca65.html#ss11.83"><CODE>.PDTV</CODE></A>
|
|
<LI><A NAME="toc11.84">11.84</A> <A HREF="ca65.html#ss11.84"><CODE>.POPCHARMAP</CODE></A>
|
|
<LI><A NAME="toc11.85">11.85</A> <A HREF="ca65.html#ss11.85"><CODE>.POPCPU</CODE></A>
|
|
<LI><A NAME="toc11.86">11.86</A> <A HREF="ca65.html#ss11.86"><CODE>.POPSEG</CODE></A>
|
|
<LI><A NAME="toc11.87">11.87</A> <A HREF="ca65.html#ss11.87"><CODE>.PROC</CODE></A>
|
|
<LI><A NAME="toc11.88">11.88</A> <A HREF="ca65.html#ss11.88"><CODE>.PSC02</CODE></A>
|
|
<LI><A NAME="toc11.89">11.89</A> <A HREF="ca65.html#ss11.89"><CODE>.PUSHCHARMAP</CODE></A>
|
|
<LI><A NAME="toc11.90">11.90</A> <A HREF="ca65.html#ss11.90"><CODE>.PUSHCPU</CODE></A>
|
|
<LI><A NAME="toc11.91">11.91</A> <A HREF="ca65.html#ss11.91"><CODE>.PUSHSEG</CODE></A>
|
|
<LI><A NAME="toc11.92">11.92</A> <A HREF="ca65.html#ss11.92"><CODE>.REFERTO, .REFTO</CODE></A>
|
|
<LI><A NAME="toc11.93">11.93</A> <A HREF="ca65.html#ss11.93"><CODE>.RELOC</CODE></A>
|
|
<LI><A NAME="toc11.94">11.94</A> <A HREF="ca65.html#ss11.94"><CODE>.REPEAT</CODE></A>
|
|
<LI><A NAME="toc11.95">11.95</A> <A HREF="ca65.html#ss11.95"><CODE>.RES</CODE></A>
|
|
<LI><A NAME="toc11.96">11.96</A> <A HREF="ca65.html#ss11.96"><CODE>.RODATA</CODE></A>
|
|
<LI><A NAME="toc11.97">11.97</A> <A HREF="ca65.html#ss11.97"><CODE>.SCOPE</CODE></A>
|
|
<LI><A NAME="toc11.98">11.98</A> <A HREF="ca65.html#ss11.98"><CODE>.SEGMENT</CODE></A>
|
|
<LI><A NAME="toc11.99">11.99</A> <A HREF="ca65.html#ss11.99"><CODE>.SET</CODE></A>
|
|
<LI><A NAME="toc11.100">11.100</A> <A HREF="ca65.html#ss11.100"><CODE>.SETCPU</CODE></A>
|
|
<LI><A NAME="toc11.101">11.101</A> <A HREF="ca65.html#ss11.101"><CODE>.SMART</CODE></A>
|
|
<LI><A NAME="toc11.102">11.102</A> <A HREF="ca65.html#ss11.102"><CODE>.STRUCT</CODE></A>
|
|
<LI><A NAME="toc11.103">11.103</A> <A HREF="ca65.html#ss11.103"><CODE>.TAG</CODE></A>
|
|
<LI><A NAME="toc11.104">11.104</A> <A HREF="ca65.html#ss11.104"><CODE>.UNDEF, .UNDEFINE</CODE></A>
|
|
<LI><A NAME="toc11.105">11.105</A> <A HREF="ca65.html#ss11.105"><CODE>.UNION</CODE></A>
|
|
<LI><A NAME="toc11.106">11.106</A> <A HREF="ca65.html#ss11.106"><CODE>.WARNING</CODE></A>
|
|
<LI><A NAME="toc11.107">11.107</A> <A HREF="ca65.html#ss11.107"><CODE>.WORD</CODE></A>
|
|
<LI><A NAME="toc11.108">11.108</A> <A HREF="ca65.html#ss11.108"><CODE>.ZEROPAGE</CODE></A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc12">12.</A> <A HREF="ca65.html#s12">Macros</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc12.1">12.1</A> <A HREF="ca65.html#ss12.1">Introduction</A>
|
|
<LI><A NAME="toc12.2">12.2</A> <A HREF="ca65.html#ss12.2">Macros without parameters</A>
|
|
<LI><A NAME="toc12.3">12.3</A> <A HREF="ca65.html#ss12.3">Parametrized macros</A>
|
|
<LI><A NAME="toc12.4">12.4</A> <A HREF="ca65.html#ss12.4">Detecting parameter types</A>
|
|
<LI><A NAME="toc12.5">12.5</A> <A HREF="ca65.html#ss12.5">Recursive macros</A>
|
|
<LI><A NAME="toc12.6">12.6</A> <A HREF="ca65.html#ss12.6">Local symbols inside macros</A>
|
|
<LI><A NAME="toc12.7">12.7</A> <A HREF="ca65.html#ss12.7">C style macros</A>
|
|
<LI><A NAME="toc12.8">12.8</A> <A HREF="ca65.html#ss12.8">Characters in macros</A>
|
|
<LI><A NAME="toc12.9">12.9</A> <A HREF="ca65.html#ss12.9">Deleting macros</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc13">13.</A> <A HREF="ca65.html#s13">Macro packages</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc13.1">13.1</A> <A HREF="ca65.html#ss13.1"><CODE>.MACPACK generic</CODE></A>
|
|
<LI><A NAME="toc13.2">13.2</A> <A HREF="ca65.html#ss13.2"><CODE>.MACPACK longbranch</CODE></A>
|
|
<LI><A NAME="toc13.3">13.3</A> <A HREF="ca65.html#ss13.3"><CODE>.MACPACK apple2</CODE></A>
|
|
<LI><A NAME="toc13.4">13.4</A> <A HREF="ca65.html#ss13.4"><CODE>.MACPACK atari</CODE></A>
|
|
<LI><A NAME="toc13.5">13.5</A> <A HREF="ca65.html#ss13.5"><CODE>.MACPACK cbm</CODE></A>
|
|
<LI><A NAME="toc13.6">13.6</A> <A HREF="ca65.html#ss13.6"><CODE>.MACPACK cpu</CODE></A>
|
|
<LI><A NAME="toc13.7">13.7</A> <A HREF="ca65.html#ss13.7"><CODE>.MACPACK module</CODE></A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc14">14.</A> <A HREF="ca65.html#s14">Predefined constants</A></H2>
|
|
|
|
<P>
|
|
<H2><A NAME="toc15">15.</A> <A HREF="ca65.html#s15">Structs and unions</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc15.1">15.1</A> <A HREF="ca65.html#ss15.1">Structs and unions Overview</A>
|
|
<LI><A NAME="toc15.2">15.2</A> <A HREF="ca65.html#ss15.2">Declaration</A>
|
|
<LI><A NAME="toc15.3">15.3</A> <A HREF="ca65.html#ss15.3">The storage allocator keywords</A>
|
|
<LI><A NAME="toc15.4">15.4</A> <A HREF="ca65.html#ss15.4">The <CODE>.ORG</CODE> keyword</A>
|
|
<LI><A NAME="toc15.5">15.5</A> <A HREF="ca65.html#ss15.5">The <CODE>.TAG</CODE> keyword</A>
|
|
<LI><A NAME="toc15.6">15.6</A> <A HREF="ca65.html#ss15.6">Limitations</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc16">16.</A> <A HREF="ca65.html#s16">Module constructors/destructors</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc16.1">16.1</A> <A HREF="ca65.html#ss16.1">Module constructors/destructors Overview</A>
|
|
<LI><A NAME="toc16.2">16.2</A> <A HREF="ca65.html#ss16.2">Calling order</A>
|
|
<LI><A NAME="toc16.3">16.3</A> <A HREF="ca65.html#ss16.3">Pitfalls</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc17">17.</A> <A HREF="ca65.html#s17">Porting sources from other assemblers</A></H2>
|
|
|
|
<UL>
|
|
<LI><A NAME="toc17.1">17.1</A> <A HREF="ca65.html#ss17.1">TASS</A>
|
|
</UL>
|
|
<P>
|
|
<H2><A NAME="toc18">18.</A> <A HREF="ca65.html#s18">Copyright</A></H2>
|
|
|
|
|
|
<HR>
|
|
<H2><A NAME="s1">1.</A> <A HREF="#toc1">Overview</A></H2>
|
|
|
|
|
|
<P>ca65 is a replacement for the ra65 assembler that was part of the cc65 C
|
|
compiler, originally developed by John R. Dunning. I had some problems with
|
|
ra65 and the copyright does not permit some things which I wanted to be
|
|
possible, so I decided to write a completely new assembler/linker/archiver
|
|
suite for the cc65 compiler. ca65 is part of this suite.</P>
|
|
<P>Some parts of the assembler (code generation and some routines for symbol
|
|
table handling) are taken from an older crossassembler named a816 written
|
|
by me a long time ago.</P>
|
|
|
|
|
|
<H2><A NAME="ss1.1">1.1</A> <A HREF="#toc1.1">Design criteria</A>
|
|
</H2>
|
|
|
|
|
|
<P>Here's a list of the design criteria, that I considered important for the
|
|
development:</P>
|
|
<P>
|
|
<UL>
|
|
<LI> The assembler must support macros. Macros are not essential, but they
|
|
make some things easier, especially when you use the assembler in the
|
|
backend of a compiler.</LI>
|
|
<LI> The assembler must support the newer 65C02 and 65816 CPUs. I have been
|
|
thinking about a 65816 backend for the C compiler, and even my old
|
|
a816 assembler had support for these CPUs, so this wasn't really a
|
|
problem.</LI>
|
|
<LI> The assembler must produce relocatable code. This is necessary for the
|
|
compiler support, and it is more convenient.</LI>
|
|
<LI> Conditional assembly must be supported. This is a must for bigger
|
|
projects written in assembler (like Elite128).</LI>
|
|
<LI> The assembler must support segments, and it must support more than
|
|
three segments (this is the count, most other assemblers support).
|
|
Having more than one code segments helps developing code for systems
|
|
with a divided ROM area (like the C64).</LI>
|
|
<LI> The linker must be able to resolve arbitrary expressions. It should
|
|
be able to get things like
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.import S1, S2
|
|
.export Special
|
|
Special = 2*S1 + S2/7
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
right.</LI>
|
|
<LI> True lexical nesting for symbols. This is very convenient for larger
|
|
assembly projects.</LI>
|
|
<LI> "Cheap" local symbols without lexical nesting for those quick, late
|
|
night hacks.</LI>
|
|
<LI> I liked the idea of "options" as Anre Fachats .o65 format has it, so I
|
|
introduced the concept into the object file format use by the new cc65
|
|
binutils.</LI>
|
|
<LI> The assembler will be a one pass assembler. There was no real need for
|
|
this decision, but I've written several multipass assemblers, and it
|
|
started to get boring. A one pass assembler needs much more elaborated
|
|
data structures, and because of that it's much more fun:-)</LI>
|
|
<LI> Non-GPLed code that may be used in any project without restrictions or
|
|
fear of "GPL infecting" other code.</LI>
|
|
</UL>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME="s2">2.</A> <A HREF="#toc2">Usage</A></H2>
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="ss2.1">2.1</A> <A HREF="#toc2.1">Command line option overview</A>
|
|
</H2>
|
|
|
|
|
|
<P>The assembler accepts the following options:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
---------------------------------------------------------------------------
|
|
Usage: ca65 [options] file
|
|
Short options:
|
|
-D name[=value] Define a symbol
|
|
-I dir Set an include directory search path
|
|
-U Mark unresolved symbols as import
|
|
-V Print the assembler version
|
|
-W n Set warning level n
|
|
-d Debug mode
|
|
-g Add debug info to object file
|
|
-h Help (this text)
|
|
-i Ignore case of symbols
|
|
-l name Create a listing file if assembly was ok
|
|
-mm model Set the memory model
|
|
-o name Name the output file
|
|
-s Enable smart mode
|
|
-t sys Set the target system
|
|
-v Increase verbosity
|
|
|
|
Long options:
|
|
--auto-import Mark unresolved symbols as import
|
|
--bin-include-dir dir Set a search path for binary includes
|
|
--cpu type Set cpu type
|
|
--create-dep name Create a make dependency file
|
|
--create-full-dep name Create a full make dependency file
|
|
--debug Debug mode
|
|
--debug-info Add debug info to object file
|
|
--feature name Set an emulation feature
|
|
--help Help (this text)
|
|
--ignore-case Ignore case of symbols
|
|
--include-dir dir Set an include directory search path
|
|
--large-alignment Don't warn about large alignments
|
|
--listing name Create a listing file if assembly was ok
|
|
--list-bytes n Maximum number of bytes per listing line
|
|
--memory-model model Set the memory model
|
|
--pagelength n Set the page length for the listing
|
|
--relax-checks Disables some error checks
|
|
--smart Enable smart mode
|
|
--target sys Set the target system
|
|
--verbose Increase verbosity
|
|
--version Print the assembler version
|
|
--warnings-as-errors Treat warnings as errors
|
|
---------------------------------------------------------------------------
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss2.2">2.2</A> <A HREF="#toc2.2">Command line options in detail</A>
|
|
</H2>
|
|
|
|
|
|
<P>Here is a description of all the command line options:</P>
|
|
<P>
|
|
<DL>
|
|
<P>
|
|
<A NAME="option--bin-include-dir"></A> </P>
|
|
<DT><B><CODE>--bin-include-dir dir</CODE></B><DD>
|
|
<P>Name a directory which is searched for binary include files. The option
|
|
may be used more than once to specify more than one directory to search. The
|
|
current directory is always searched first before considering any
|
|
additional directories. See also the section about
|
|
<A HREF="#search-paths">search paths</A>.</P>
|
|
|
|
<P>
|
|
<A NAME="option--cpu"></A> </P>
|
|
<DT><B><CODE>--cpu type</CODE></B><DD>
|
|
<P>Set the default for the CPU type. The option takes a parameter, which
|
|
may be one of</P>
|
|
<P>6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, sweet16, HuC6280, 4510</P>
|
|
|
|
<P>
|
|
<A NAME="option-create-dep"></A> </P>
|
|
<DT><B><CODE>--create-dep name</CODE></B><DD>
|
|
<P>Tells the assembler to generate a file containing the dependency list for
|
|
the assembled module in makefile syntax. The output is written to a file
|
|
with the given name. The output does not include files passed via debug
|
|
information to the assembler.</P>
|
|
|
|
<P>
|
|
<A NAME="option-create-full-dep"></A> </P>
|
|
<DT><B><CODE>--create-full-dep name</CODE></B><DD>
|
|
<P>Tells the assembler to generate a file containing the dependency list for
|
|
the assembled module in makefile syntax. The output is written to a file
|
|
with the given name. The output does include files passed via debug
|
|
information to the assembler.</P>
|
|
|
|
|
|
<DT><B><CODE>-d, --debug</CODE></B><DD>
|
|
<P>Enables debug mode, something that should not be needed for mere
|
|
mortals:-)</P>
|
|
|
|
<P>
|
|
<A NAME="option--feature"></A> </P>
|
|
<DT><B><CODE>--feature name</CODE></B><DD>
|
|
<P>Enable an emulation feature. This is identical as using <CODE>.FEATURE</CODE>
|
|
in the source with two exceptions: Feature names must be lower case, and
|
|
each feature must be specified by using a separate <CODE>--feature</CODE> option,
|
|
comma separated lists are not allowed.</P>
|
|
<P>See the discussion of the <CODE>
|
|
<A HREF="#.FEATURE">.FEATURE</A></CODE>
|
|
command for a list of emulation features.</P>
|
|
|
|
<P>
|
|
<A NAME="option-g"></A> </P>
|
|
<DT><B><CODE>-g, --debug-info</CODE></B><DD>
|
|
<P>When this option (or the equivalent control command <CODE>.DEBUGINFO</CODE>) is
|
|
used, the assembler will add a section to the object file that contains
|
|
all symbols (including local ones) together with the symbol values and
|
|
source file positions. The linker will put these additional symbols into
|
|
the VICE label file, so even local symbols can be seen in the VICE
|
|
monitor.</P>
|
|
|
|
<P>
|
|
<A NAME="option-h"></A> </P>
|
|
<DT><B><CODE>-h, --help</CODE></B><DD>
|
|
<P>Print the short option summary shown above.</P>
|
|
|
|
<P>
|
|
<A NAME="option-i"></A> </P>
|
|
<DT><B><CODE>-i, --ignore-case</CODE></B><DD>
|
|
<P>This option makes the assembler case insensitive on identifiers and labels.
|
|
This option will override the default, but may itself be overridden by the
|
|
<CODE>
|
|
<A HREF="#.CASE">.CASE</A></CODE> control command.</P>
|
|
|
|
<P>
|
|
<A NAME="option-l"></A> </P>
|
|
<DT><B><CODE>-l name, --listing name</CODE></B><DD>
|
|
<P>Generate an assembler listing with the given name. A listing file will
|
|
never be generated in case of assembly errors.</P>
|
|
|
|
<P>
|
|
<A NAME="option--large-alignment"></A> </P>
|
|
<DT><B><CODE>--large-alignment</CODE></B><DD>
|
|
<P>Disable warnings about a large combined alignment. See the discussion of the
|
|
<CODE>
|
|
<A HREF="#.ALIGN">.ALIGN</A></CODE> directive for further information.</P>
|
|
|
|
<P>
|
|
<A NAME="option--list-bytes"></A> </P>
|
|
<DT><B><CODE>--list-bytes n</CODE></B><DD>
|
|
<P>Set the maximum number of bytes printed in the listing for one line of
|
|
input. See the <CODE>
|
|
<A HREF="#.LISTBYTES">.LISTBYTES</A></CODE> directive
|
|
for more information. The value zero can be used to encode an unlimited
|
|
number of printed bytes.</P>
|
|
|
|
<P>
|
|
<A NAME="option-mm"></A> </P>
|
|
<DT><B><CODE>-mm model, --memory-model model</CODE></B><DD>
|
|
<P>Define the default memory model. Possible model specifiers are near, far and
|
|
huge.</P>
|
|
|
|
<P>
|
|
<A NAME="option-o"></A> </P>
|
|
<DT><B><CODE>-o name</CODE></B><DD>
|
|
<P>The default output name is the name of the input file with the extension
|
|
replaced by ".o". If you don't like that, you may give another name with
|
|
the -o option. The output file will be placed in the same directory as
|
|
the source file, or, if -o is given, the full path in this name is used.</P>
|
|
|
|
<P>
|
|
<A NAME="option--pagelength"></A> </P>
|
|
<DT><B><CODE>--pagelength n</CODE></B><DD>
|
|
<P>sets the length of a listing page in lines. See the <CODE>
|
|
<A HREF="#.PAGELENGTH">.PAGELENGTH</A></CODE> directive for more information.</P>
|
|
|
|
<P>
|
|
<A NAME="option--relax-checks"></A> </P>
|
|
<DT><B><CODE>--relax-checks</CODE></B><DD>
|
|
<P>Disables some error checks done by the assembler. This will allow code that is an
|
|
error in most cases and flagged as such by the assembler, but can be valid
|
|
in special situations.</P>
|
|
<P>Disabled checks are:
|
|
<UL>
|
|
<LI>Address vs. fragment size: a byte sized load from an non-zeropage
|
|
address is truncated instead of producing an error.</LI>
|
|
<LI>Indirect jump on page boundary: <CODE>jmp (label)</CODE> on a label that
|
|
resides on a page boundary (<CODE>$xxFF</CODE>) fetches the second byte from the
|
|
wrong address on 6502 CPUs, now allowed instead of producing an error.</LI>
|
|
</UL>
|
|
</P>
|
|
|
|
<P>
|
|
<A NAME="option-s"></A> </P>
|
|
<DT><B><CODE>-s, --smart-mode</CODE></B><DD>
|
|
<P>In smart mode (enabled by -s or the <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE>
|
|
pseudo instruction) the assembler will track usage of the <CODE>REP</CODE> and
|
|
<CODE>SEP</CODE> 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.</P>
|
|
<P>Beware: Since the assembler cannot trace the execution flow this may
|
|
lead to false results in some cases. If in doubt, use the .ixx and .axx
|
|
instructions to tell the assembler about the current settings. Smart
|
|
mode is off by default.</P>
|
|
|
|
<P>
|
|
<A NAME="option-t"></A> </P>
|
|
<DT><B><CODE>-t sys, --target sys</CODE></B><DD>
|
|
<P>Set the target system. This will enable translation of character strings and
|
|
character constants into the character set of the target platform. The
|
|
default for the target system is "none", which means that no translation
|
|
will take place. The assembler supports the same target systems as the
|
|
compiler, see there for a list.</P>
|
|
<P>Depending on the target, the default CPU type is also set. This can be
|
|
overridden by using the <CODE>
|
|
<A HREF="#option--cpu">--cpu</A></CODE> option.</P>
|
|
|
|
<P>
|
|
<A NAME="option-v"></A> </P>
|
|
<DT><B><CODE>-v, --verbose</CODE></B><DD>
|
|
<P>Increase the assembler verbosity. Usually only needed for debugging
|
|
purposes. You may use this option more than one time for even more
|
|
verbose output.</P>
|
|
|
|
<P>
|
|
<A NAME="option-D"></A> </P>
|
|
<DT><B><CODE>-D</CODE></B><DD>
|
|
<P>This option allows you to define symbols on the command line. Without a
|
|
value, the symbol is defined with the value zero. When giving a value,
|
|
you may use the '$' prefix for hexadecimal symbols. Please note
|
|
that for some operating systems, '$' has a special meaning, so
|
|
you may have to quote the expression.</P>
|
|
|
|
<P>
|
|
<A NAME="option-I"></A> </P>
|
|
<DT><B><CODE>-I dir, --include-dir dir</CODE></B><DD>
|
|
<P>Name a directory which is searched for include files. The option may be
|
|
used more than once to specify more than one directory to search. The
|
|
current directory is always searched first before considering any
|
|
additional directories. See also the section about
|
|
<A HREF="#search-paths">search paths</A>.</P>
|
|
|
|
<P>
|
|
<A NAME="option-U"></A> </P>
|
|
<DT><B><CODE>-U, --auto-import</CODE></B><DD>
|
|
<P>Mark symbols that are not defined in the sources as imported symbols. This
|
|
should be used with care since it delays error messages about typos and such
|
|
until the linker is run. The compiler uses the equivalent of this switch
|
|
(<CODE>
|
|
<A HREF="#.AUTOIMPORT">.AUTOIMPORT</A></CODE>) to enable auto imported
|
|
symbols for the runtime library. However, the compiler is supposed to
|
|
generate code that runs through the assembler without problems, something
|
|
which is not always true for assembler programmers.</P>
|
|
|
|
<P>
|
|
<A NAME="option-V"></A> </P>
|
|
<DT><B><CODE>-V, --version</CODE></B><DD>
|
|
<P>Print the version number of the assembler. If you send any suggestions
|
|
or bugfixes, please include the version number.</P>
|
|
|
|
<P>
|
|
<A NAME="option-W"></A> </P>
|
|
<DT><B><CODE>-Wn</CODE></B><DD>
|
|
<P>Set the warning level for the assembler. Using -W2 the assembler will
|
|
even warn about such things like unused imported symbols. The default
|
|
warning level is 1, and it would probably be silly to set it to
|
|
something lower.</P>
|
|
|
|
<P>
|
|
<A NAME="option--warnings-as-errors"></A> </P>
|
|
<DT><B><CODE>--warnings-as-errors</CODE></B><DD>
|
|
<P>An error will be generated if any warnings were produced.</P>
|
|
|
|
|
|
</DL>
|
|
</P>
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="search-paths"></A> <A NAME="s3">3.</A> <A HREF="#toc3">Search paths</A></H2>
|
|
|
|
|
|
<P>Normal include files are searched in the following places:</P>
|
|
<P>
|
|
<OL>
|
|
<LI>The current file's directory.</LI>
|
|
<LI>Any directory added with the <CODE>
|
|
<A HREF="#option-I">-I</A></CODE> option
|
|
on the command line.</LI>
|
|
<LI>The value of the environment variable <CODE>CA65_INC</CODE> if it is defined.</LI>
|
|
<LI>A subdirectory named <CODE>asminc</CODE> of the directory defined in the
|
|
environment variable <CODE>CC65_HOME</CODE>, if it is defined.</LI>
|
|
<LI>An optionally compiled-in directory.</LI>
|
|
</OL>
|
|
</P>
|
|
<P>Binary include files are searched in the following places:</P>
|
|
<P>
|
|
<OL>
|
|
<LI>The current file's directory.</LI>
|
|
<LI>Any directory added with the <CODE>
|
|
<A HREF="#option--bin-include-dir">--bin-include-dir</A></CODE> option on the command line.</LI>
|
|
</OL>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME="s4">4.</A> <A HREF="#toc4">Input format</A></H2>
|
|
|
|
|
|
|
|
<H2><A NAME="ss4.1">4.1</A> <A HREF="#toc4.1">Assembler syntax</A>
|
|
</H2>
|
|
|
|
|
|
<P>The assembler accepts the standard 6502/65816 assembler syntax. One line may
|
|
contain a label (which is identified by a colon), and, in addition to the
|
|
label, an assembler mnemonic, a macro, or a control command (see section
|
|
<A HREF="#control-commands">Control Commands</A> for supported control
|
|
commands). Alternatively, the line may contain a symbol definition using
|
|
the '=' token. Everything after a semicolon is handled as a comment (that is,
|
|
it is ignored).</P>
|
|
<P>Here are some examples for valid input lines:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
Label: ; A label and a comment
|
|
lda #$20 ; A 6502 instruction plus comment
|
|
L1: ldx #$20 ; Same with label
|
|
L2: .byte "Hello world" ; Label plus control command
|
|
mymac $20 ; Macro expansion
|
|
MySym = 3*L1 ; Symbol definition
|
|
MaSym = Label ; Another symbol
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The assembler accepts</P>
|
|
<P>
|
|
<UL>
|
|
<LI>all valid 6502 mnemonics when in 6502 mode (the default or after the
|
|
<CODE>
|
|
<A HREF="#.P02">.P02</A></CODE> command was given).</LI>
|
|
<LI>all valid 6502 mnemonics plus a set of illegal instructions when in
|
|
<A HREF="#6502X-mode">6502X mode</A>.</LI>
|
|
<LI>all valid 6502DTV mnemonics when in 6502DTV mode (after the
|
|
<CODE>
|
|
<A HREF="#.PDTV">.PDTV</A></CODE> command was given).</LI>
|
|
<LI>all valid 65SC02 mnemonics when in 65SC02 mode (after the
|
|
<CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE> command was given).</LI>
|
|
<LI>all valid 65C02 mnemonics when in 65C02 mode (after the
|
|
<CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE> command was given).</LI>
|
|
<LI>all valid 65816 mnemonics when in 65816 mode (after the
|
|
<CODE>
|
|
<A HREF="#.P816">.P816</A></CODE> command was given).</LI>
|
|
<LI>all valid 4510 mnemonics when in 4510 mode (after the
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE> command was given).</LI>
|
|
</UL>
|
|
</P>
|
|
<P>On 6502-derived platforms the <CODE>BRK</CODE> instruction has an optional signature
|
|
byte. If omitted, the assembler will only produce only 1 byte.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
brk ; 1-byte: $00
|
|
brk $34 ; 2-bytes: $00 $34
|
|
brk #$34 ; 2-bytes: $00 $34
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss4.2">4.2</A> <A HREF="#toc4.2">65816 mode</A>
|
|
</H2>
|
|
|
|
|
|
<P>In 65816 mode, several aliases are accepted, in addition to the official
|
|
mnemonics:</P>
|
|
<P>
|
|
<UL>
|
|
<LI><CODE>CPA</CODE> is an alias for <CODE>CMP</CODE></LI>
|
|
<LI><CODE>DEA</CODE> is an alias for <CODE>DEC A</CODE></LI>
|
|
<LI><CODE>INA</CODE> is an alias for <CODE>INC A</CODE></LI>
|
|
<LI><CODE>SWA</CODE> is an alias for <CODE>XBA</CODE></LI>
|
|
<LI><CODE>TAD</CODE> is an alias for <CODE>TCD</CODE></LI>
|
|
<LI><CODE>TAS</CODE> is an alias for <CODE>TCS</CODE></LI>
|
|
<LI><CODE>TDA</CODE> is an alias for <CODE>TDC</CODE></LI>
|
|
<LI><CODE>TSA</CODE> is an alias for <CODE>TSC</CODE></LI>
|
|
</UL>
|
|
</P>
|
|
<P>The <CODE>MVN</CODE> and <CODE>MVP</CODE> instructions accept two different argument forms.
|
|
Either two bank bytes may be given with a <CODE>#</CODE> prefix,
|
|
or two far addresses whose high byte will be used.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
mvn #^src, #^dst ; bank of src to bank of dst
|
|
mvn src, dst ; bank of src to bank of dst
|
|
mvp #$12, #$78 ; bank $12 to $78
|
|
mvp $123456, $789ABC ; bank $12 to $78
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="6502X-mode"></A> <A NAME="ss4.3">4.3</A> <A HREF="#toc4.3">6502X mode</A>
|
|
</H2>
|
|
|
|
|
|
<P>6502X mode is an extension to the normal 6502 mode. In this mode, several
|
|
mnemonics for illegal instructions of the NMOS 6502 CPUs are accepted. Since
|
|
these instructions are illegal, there are no official mnemonics for them. The
|
|
unofficial ones are taken from
|
|
<A HREF="http://www.oxyron.de/html/opcodes02.html">http://www.oxyron.de/html/opcodes02.html</A>. Please note that only the
|
|
ones marked as "stable" are supported. The following table uses information
|
|
from the mentioned web page, for more information, see there.</P>
|
|
<P>
|
|
<UL>
|
|
<LI><CODE>ALR: A:=(A and #{imm})/2;</CODE></LI>
|
|
<LI><CODE>ANC: A:=A and #{imm};</CODE> Generates opcode $0B.</LI>
|
|
<LI><CODE>ARR: A:=(A and #{imm})/2;</CODE></LI>
|
|
<LI><CODE>AXS: X:=A and X-#{imm};</CODE></LI>
|
|
<LI><CODE>DCP: {adr}:={adr}-1; A-{adr};</CODE></LI>
|
|
<LI><CODE>ISC: {adr}:={adr}+1; A:=A-{adr};</CODE></LI>
|
|
<LI><CODE>LAS: A,X,S:={adr} and S;</CODE></LI>
|
|
<LI><CODE>LAX: A,X:={adr};</CODE></LI>
|
|
<LI><CODE>RLA: {adr}:={adr}rol; A:=A and {adr};</CODE></LI>
|
|
<LI><CODE>RRA: {adr}:={adr}ror; A:=A adc {adr};</CODE></LI>
|
|
<LI><CODE>SAX: {adr}:=A and X;</CODE></LI>
|
|
<LI><CODE>SLO: {adr}:={adr}*2; A:=A or {adr};</CODE></LI>
|
|
<LI><CODE>SRE: {adr}:={adr}/2; A:=A xor {adr};</CODE></LI>
|
|
</UL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss4.4">4.4</A> <A HREF="#toc4.4">4510 mode</A>
|
|
</H2>
|
|
|
|
|
|
<P>The 4510 is a microcontroller that is the core of the Commodore C65 aka C64DX.
|
|
It contains among other functions a slightly modified 65CE02/4502 CPU, to allow
|
|
address mapping for 20 bits of address space (1 megabyte addressable area).
|
|
As compared to the description of the CPU in the
|
|
<A HREF="http://www.zimmers.net/anonftp/pub/cbm/c65/c65manualupdated.txt.gz">C65 System Specification</A>
|
|
<A HREF="https://raw.githubusercontent.com/MEGA65/c65-specifications/master/c65manualupdated.txt">(updated version)</A> uses these changes:
|
|
<UL>
|
|
<LI><CODE>LDA (d,SP),Y</CODE> may also be written as <CODE>LDA (d,S),Y</CODE>
|
|
(matching the 65816 notataion).</LI>
|
|
<LI>All branch instruction allow now 16 bit offsets. To use a 16 bit
|
|
branch you have to prefix these with an "L" (e.g. "<CODE>LBNE</CODE>" instead of
|
|
"<CODE>BNE</CODE>"). This might change at a later implementation of the assembler.</LI>
|
|
</UL>
|
|
|
|
For more information about the Commodore C65/C64DX and the 4510 CPU, see
|
|
<A HREF="http://www.zimmers.net/anonftp/pub/cbm/c65/">http://www.zimmers.net/anonftp/pub/cbm/c65/</A> and
|
|
<A HREF="https://en.wikipedia.org/wiki/Commodore_65">Wikipedia</A>.</P>
|
|
|
|
|
|
<H2><A NAME="sweet16-mode"></A> <A NAME="ss4.5">4.5</A> <A HREF="#toc4.5">sweet16 mode</A>
|
|
</H2>
|
|
|
|
|
|
<P>SWEET 16 is an interpreter for a pseudo 16 bit CPU written by Steve Wozniak
|
|
for the Apple ][ machines. It is available in the Apple ][ ROM. ca65 can
|
|
generate code for this pseudo CPU when switched into sweet16 mode. The
|
|
following is special in sweet16 mode:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>The '@' character denotes indirect addressing and is no longer available
|
|
for cheap local labels. If you need cheap local labels, you will have to
|
|
switch to another lead character using the <CODE>
|
|
<A HREF="#.LOCALCHAR">.LOCALCHAR</A></CODE> command.
|
|
</LI>
|
|
<LI>Registers are specified using <CODE>R0</CODE> .. <CODE>R15</CODE>. In sweet16 mode,
|
|
these identifiers are reserved words.
|
|
</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Please note that the assembler does neither supply the interpreter needed for
|
|
SWEET 16 code, nor the zero page locations needed for the SWEET 16 registers,
|
|
nor does it call the interpreter. All this must be done by your program. Apple
|
|
][ programmers do probably know how to use sweet16 mode.</P>
|
|
<P>For more information about SWEET 16, see
|
|
<A HREF="http://www.6502.org/source/interpreters/sweet16.htm">http://www.6502.org/source/interpreters/sweet16.htm</A>.</P>
|
|
|
|
|
|
<H2><A NAME="ss4.6">4.6</A> <A HREF="#toc4.6">Number format</A>
|
|
</H2>
|
|
|
|
|
|
<P>For literal values, the assembler accepts the widely used number formats: A
|
|
preceding '$' or a trailing 'h' denotes a hex value, a preceding '%'
|
|
denotes a binary value, and a bare number is interpreted as a decimal. There
|
|
are currently no octal values and no floats.</P>
|
|
|
|
|
|
<H2><A NAME="ss4.7">4.7</A> <A HREF="#toc4.7">Conditional assembly</A>
|
|
</H2>
|
|
|
|
|
|
<P>Please note that when using the conditional directives (<CODE>.IF</CODE> and friends),
|
|
the input must consist of valid assembler tokens, even in <CODE>.IF</CODE> branches
|
|
that are not assembled. The reason for this behaviour is that the assembler
|
|
must still be able to detect the ending tokens (like <CODE>.ENDIF</CODE>), so
|
|
conversion of the input stream into tokens still takes place. As a consequence
|
|
conditional assembly directives may <B>not</B> be used to prevent normal text
|
|
(used as a comment or similar) from being assembled. </P>
|
|
|
|
|
|
|
|
<H2><A NAME="s5">5.</A> <A HREF="#toc5">Expressions</A></H2>
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Expression evaluation</A>
|
|
</H2>
|
|
|
|
|
|
<P>All expressions are evaluated with (at least) 32 bit precision. An
|
|
expression may contain constant values and any combination of internal and
|
|
external symbols. Expressions that cannot be evaluated at assembly time
|
|
are stored inside the object file for evaluation by the linker.
|
|
Expressions referencing imported symbols must always be evaluated by the
|
|
linker.</P>
|
|
|
|
|
|
<H2><A NAME="ss5.2">5.2</A> <A HREF="#toc5.2">Size of an expression result</A>
|
|
</H2>
|
|
|
|
|
|
<P>Sometimes, the assembler must know about the size of the value that is the
|
|
result of an expression. This is usually the case, if a decision has to be
|
|
made, to generate a zero page or an absolute memory references. In this
|
|
case, the assembler has to make some assumptions about the result of an
|
|
expression:</P>
|
|
<P>
|
|
<UL>
|
|
<LI> If the result of an expression is constant, the actual value is
|
|
checked to see if it's a byte sized expression or not.</LI>
|
|
<LI> If the expression is explicitly casted to a byte sized expression by
|
|
one of the '>', '<' or '^' operators, it is a byte expression.</LI>
|
|
<LI> If this is not the case, and the expression contains a symbol,
|
|
explicitly declared as zero page symbol (by one of the .importzp or
|
|
.exportzp instructions), then the whole expression is assumed to be
|
|
byte sized.</LI>
|
|
<LI> If the expression contains symbols that are not defined, and these
|
|
symbols are local symbols, the enclosing scopes are searched for a
|
|
symbol with the same name. If one exists and this symbol is defined,
|
|
its attributes are used to determine the result size.</LI>
|
|
<LI> In all other cases the expression is assumed to be word sized.</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Note: If the assembler is not able to evaluate the expression at assembly
|
|
time, the linker will evaluate it and check for range errors as soon as
|
|
the result is known.</P>
|
|
|
|
|
|
<H2><A NAME="ss5.3">5.3</A> <A HREF="#toc5.3">Boolean expressions</A>
|
|
</H2>
|
|
|
|
|
|
<P>In the context of a boolean expression, any non zero value is evaluated as
|
|
true, any other value to false. The result of a boolean expression is 1 if
|
|
it's true, and zero if it's false. There are boolean operators with extreme
|
|
low precedence with version 2.x (where x > 0). The <CODE>.AND</CODE> and <CODE>.OR</CODE>
|
|
operators are shortcut operators. That is, if the result of the expression is
|
|
already known, after evaluating the left hand side, the right hand side is
|
|
not evaluated.</P>
|
|
|
|
|
|
<H2><A NAME="ss5.4">5.4</A> <A HREF="#toc5.4">Constant expressions</A>
|
|
</H2>
|
|
|
|
|
|
<P>Sometimes an expression must evaluate to a constant without looking at any
|
|
further input. One such example is the <CODE>
|
|
<A HREF="#.IF">.IF</A></CODE> command
|
|
that decides if parts of the code are assembled or not. An expression used in
|
|
the <CODE>.IF</CODE> command cannot reference a symbol defined later, because the
|
|
decision about the <CODE>.IF</CODE> must be made at the point when it is read. If the
|
|
expression used in such a context contains only constant numerical values,
|
|
there is no problem. When unresolvable symbols are involved it may get harder
|
|
for the assembler to determine if the expression is actually constant, and it
|
|
is even possible to create expressions that aren't recognized as constant.
|
|
Simplifying the expressions will often help.</P>
|
|
<P>In cases where the result of the expression is not needed immediately, the
|
|
assembler will delay evaluation until all input is read, at which point all
|
|
symbols are known. So using arbitrary complex constant expressions is no
|
|
problem in most cases.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="operators"></A> <A NAME="ss5.5">5.5</A> <A HREF="#toc5.5">Available operators</A>
|
|
</H2>
|
|
|
|
|
|
<P>
|
|
<BR><CENTER>
|
|
<TABLE BORDER><TR><TD>
|
|
<B>Operator</B></TD><TD> <B>Description</B></TD><TD> <B>Precedence</B></TD></TR><TR><TD>
|
|
</TD><TD> Built-in string functions</TD><TD> 0</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
</TD><TD> Built-in pseudo-variables</TD><TD> 1</TD></TR><TR><TD>
|
|
</TD><TD> Built-in pseudo-functions</TD><TD> 1</TD></TR><TR><TD>
|
|
+</TD><TD> Unary positive</TD><TD> 1</TD></TR><TR><TD>
|
|
-</TD><TD> Unary negative</TD><TD> 1</TD></TR><TR><TD>
|
|
~<BR>.BITNOT</TD><TD> Unary bitwise not</TD><TD> 1</TD></TR><TR><TD>
|
|
<<BR>.LOBYTE</TD><TD> Unary low-byte operator</TD><TD> 1</TD></TR><TR><TD>
|
|
><BR>.HIBYTE</TD><TD> Unary high-byte operator</TD><TD> 1</TD></TR><TR><TD>
|
|
^<BR>.BANKBYTE</TD><TD> Unary bank-byte operator</TD><TD> 1</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
*</TD><TD> Multiplication</TD><TD> 2</TD></TR><TR><TD>
|
|
/</TD><TD> Division</TD><TD> 2</TD></TR><TR><TD>
|
|
.MOD</TD><TD> Modulo operator</TD><TD> 2</TD></TR><TR><TD>
|
|
&<BR>.BITAND</TD><TD> Bitwise and</TD><TD> 2</TD></TR><TR><TD>
|
|
^<BR>.BITXOR</TD><TD> Binary bitwise xor</TD><TD> 2</TD></TR><TR><TD>
|
|
<<<BR>.SHL</TD><TD> Shift-left operator</TD><TD> 2</TD></TR><TR><TD>
|
|
>><BR>.SHR</TD><TD> Shift-right operator</TD><TD> 2</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
+</TD><TD> Binary addition</TD><TD> 3</TD></TR><TR><TD>
|
|
-</TD><TD> Binary subtraction</TD><TD> 3</TD></TR><TR><TD>
|
|
|<BR>.BITOR</TD><TD> Bitwise or</TD><TD> 3</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
= </TD><TD> Compare operator (equal)</TD><TD> 4</TD></TR><TR><TD>
|
|
<></TD><TD> Compare operator (not equal)</TD><TD> 4</TD></TR><TR><TD>
|
|
<</TD><TD> Compare operator (less)</TD><TD> 4</TD></TR><TR><TD>
|
|
></TD><TD> Compare operator (greater)</TD><TD> 4</TD></TR><TR><TD>
|
|
<=</TD><TD> Compare operator (less or equal)</TD><TD> 4</TD></TR><TR><TD>
|
|
>=</TD><TD> Compare operator (greater or equal)</TD><TD> 4</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
&&<BR>.AND</TD><TD> Boolean and</TD><TD> 5</TD></TR><TR><TD>
|
|
.XOR</TD><TD> Boolean xor</TD><TD> 5</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
||<BR>.OR</TD><TD> Boolean or</TD><TD> 6</TD></TR><TR><TD>
|
|
</TD><TD> </TD><TD> </TD></TR><TR><TD>
|
|
!<BR>.NOT</TD><TD> Boolean not</TD><TD> 7
|
|
</TD></TR></TABLE>
|
|
<CAPTION>Available operators, sorted by precedence</CAPTION>
|
|
</CENTER><BR>
|
|
</P>
|
|
<P>To force a specific order of evaluation, parentheses may be used, as usual.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="s6">6.</A> <A HREF="#toc6">Symbols and labels</A></H2>
|
|
|
|
|
|
<P>A symbol or label is an identifier that starts with a letter and is followed
|
|
by letters and digits. Depending on some features enabled (see
|
|
<CODE>
|
|
<A HREF="#at_in_identifiers">at_in_identifiers</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#dollar_in_identifiers">dollar_in_identifiers</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#leading_dot_in_identifiers">leading_dot_in_identifiers</A></CODE>)
|
|
other characters may be present. Use of identifiers consisting of a single
|
|
character will not work in all cases, because some of these identifiers are
|
|
reserved keywords (for example "A" is not a valid identifier for a label,
|
|
because it is the keyword for the accumulator).</P>
|
|
<P>The assembler allows you to use symbols instead of naked values to make
|
|
the source more readable. There are a lot of different ways to define and
|
|
use symbols and labels, giving a lot of flexibility.</P>
|
|
|
|
<H2><A NAME="ss6.1">6.1</A> <A HREF="#toc6.1">Numeric constants</A>
|
|
</H2>
|
|
|
|
|
|
<P>Numeric constants are defined using the equal sign or the label assignment
|
|
operator. After doing</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
two = 2
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>may use the symbol "two" in every place where a number is expected, and it is
|
|
evaluated to the value 2 in this context. The label assignment operator is
|
|
almost identical, but causes the symbol to be marked as a label, so it may be
|
|
handled differently in a debugger:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
io := $d000
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The right side can of course be an expression:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
four = two * two
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
<P>
|
|
<A NAME="variables"></A> </P>
|
|
<H2><A NAME="ss6.2">6.2</A> <A HREF="#toc6.2">Numeric variables</A>
|
|
</H2>
|
|
|
|
|
|
<P>Within macros and other control structures (<CODE>
|
|
<A HREF="#.REPEAT">.REPEAT</A></CODE>, ...) it is sometimes useful to have some sort of
|
|
variable. This can be achieved by the <CODE>.SET</CODE> operator. It creates a
|
|
symbol that may get assigned a different value later:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
four .set 4
|
|
lda #four ; Loads 4 into A
|
|
four .set 3
|
|
lda #four ; Loads 3 into A
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Since the value of the symbol can change later, it must be possible to
|
|
evaluate it when used (no delayed evaluation as with normal symbols). So the
|
|
expression used as the value must be constant.</P>
|
|
<P>Following is an example for a macro that generates a different label each time
|
|
it is used. It uses the <CODE>
|
|
<A HREF="#.SPRINTF">.SPRINTF</A></CODE> function
|
|
and a numeric variable named <CODE>lcount</CODE>.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.lcount .set 0 ; Initialize the counter
|
|
|
|
.macro genlab
|
|
.ident (.sprintf ("L%04X", lcount)):
|
|
lcount .set lcount + 1
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss6.3">6.3</A> <A HREF="#toc6.3">Standard labels</A>
|
|
</H2>
|
|
|
|
|
|
<P>A label is defined by writing the name of the label at the start of the line
|
|
(before any instruction mnemonic, macro or pseudo directive), followed by a
|
|
colon. This will declare a symbol with the given name and the value of the
|
|
current program counter.</P>
|
|
|
|
|
|
<H2><A NAME="ss6.4">6.4</A> <A HREF="#toc6.4">Local labels and symbols</A>
|
|
</H2>
|
|
|
|
|
|
<P>Using the <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE> directive, it is possible to
|
|
create regions of code where the names of labels and symbols are local to this
|
|
region. They are not known outside of this region and cannot be accessed from
|
|
there. Such regions may be nested like PROCEDUREs in Pascal.</P>
|
|
<P>See the description of the <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE>
|
|
directive for more information.</P>
|
|
|
|
|
|
<H2><A NAME="ss6.5">6.5</A> <A HREF="#toc6.5">Cheap local labels</A>
|
|
</H2>
|
|
|
|
|
|
<P>Cheap local labels are defined like standard labels, but the name of the
|
|
label must begin with a special symbol (usually '@', but this can be
|
|
changed by the <CODE>
|
|
<A HREF="#.LOCALCHAR">.LOCALCHAR</A></CODE>
|
|
directive).</P>
|
|
<P>Cheap local labels are visible only between two non cheap labels. As soon as a
|
|
standard symbol is encountered (this may also be a local symbol if inside a
|
|
region defined with the <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE> directive), the
|
|
cheap local symbol goes out of scope.</P>
|
|
<P>You may use cheap local labels as an easy way to reuse common label
|
|
names like "Loop". Here is an example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
Clear: lda #$00 ; Global label
|
|
ldy #$20
|
|
@Loop: sta Mem,y ; Local label
|
|
dey
|
|
bne @Loop ; Ok
|
|
rts
|
|
Sub: ... ; New global label
|
|
bne @Loop ; ERROR: Unknown identifier!
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss6.6">6.6</A> <A HREF="#toc6.6">Unnamed labels</A>
|
|
</H2>
|
|
|
|
|
|
<P>If you really want to write messy code, there are also unnamed labels. To define
|
|
an unnamed label, use either <CODE>@:</CODE> (<CODE>.LOCALCHAR</CODE> is respected if it
|
|
is set) or sole <CODE>:</CODE>.</P>
|
|
<P>To reference an unnamed label, use <CODE>@</CODE> (<CODE>.LOCALCHAR</CODE> is respected
|
|
if it is set) or <CODE>:</CODE> with several <CODE>-</CODE> or <CODE>+</CODE> characters.
|
|
The <CODE>-</CODE> characters will create a back reference (n'th label backwards),
|
|
the <CODE>+</CODE> will create a forward reference (n'th label in forward direction).
|
|
As an alternative, angle brackets <CODE><</CODE> and <CODE>></CODE> may be used
|
|
instead of <CODE>-</CODE> and <CODE>+</CODE> with the same meaning.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
cpy #0
|
|
beq @++
|
|
@:
|
|
sta $2007
|
|
dey
|
|
bne @-
|
|
@:
|
|
rts
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Unnamed labels may make even short sections of code hard to understand, because
|
|
you have to count labels to find branch targets. It's better to prefer the
|
|
"cheap" local labels. Nevertheless, unnamed labels are convenient in some
|
|
situations, so it's up to your discretion.</P>
|
|
<P><EM>Note:</EM>
|
|
<A HREF="#scopes">Scopes</A> organize named symbols, not
|
|
unnamed ones, so scopes don't have an effect on unnamed labels.</P>
|
|
|
|
|
|
<H2><A NAME="ss6.7">6.7</A> <A HREF="#toc6.7">Using macros to define labels and constants</A>
|
|
</H2>
|
|
|
|
|
|
<P>While there are drawbacks with this approach, it may be handy in a few rare
|
|
situations. Using <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE>, it is possible
|
|
to define symbols or constants that may be used elsewhere. One of the
|
|
advantages is that you can use it to define string constants (this is not
|
|
possible with the other symbol types).</P>
|
|
<P>Please note: <CODE>.DEFINE</CODE> style macros do token replacements on a low level,
|
|
so the names do not adhere to scoping, diagnostics may be misleading, there
|
|
are no symbols to look up in the map file, and there is no debug info.
|
|
Especially the first problem in the list can lead to very nasty programming
|
|
errors. Because of these problems, the general advice is, <B>NOT</B> do use
|
|
<CODE>.DEFINE</CODE> if you don't have to.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.DEFINE two 2
|
|
.DEFINE version "SOS V2.3"
|
|
|
|
four = two * two ; Ok
|
|
.byte version ; Ok
|
|
|
|
.PROC ; Start local scope
|
|
two = 3 ; Will give "2 = 3" - invalid!
|
|
.ENDPROC
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss6.8">6.8</A> <A HREF="#toc6.8">Symbols and <CODE>.DEBUGINFO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>If <CODE>
|
|
<A HREF="#.DEBUGINFO">.DEBUGINFO</A></CODE> is enabled (or
|
|
<A HREF="#option-g">-g</A> is given on the command line), global, local and
|
|
cheap local labels are written to the object file and will be available in the
|
|
symbol file via the linker. Unnamed labels are not written to the object file,
|
|
because they don't have a name which would allow to access them.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="scopes"></A> <A NAME="s7">7.</A> <A HREF="#toc7">Scopes</A></H2>
|
|
|
|
|
|
<P>ca65 implements several sorts of scopes for symbols.</P>
|
|
|
|
<H2><A NAME="ss7.1">7.1</A> <A HREF="#toc7.1">Global scope</A>
|
|
</H2>
|
|
|
|
|
|
<P>All (non cheap local) symbols that are declared outside of any nested scopes
|
|
are in global scope.</P>
|
|
|
|
|
|
<H2><A NAME="ss7.2">7.2</A> <A HREF="#toc7.2">Cheap locals</A>
|
|
</H2>
|
|
|
|
|
|
<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.</P>
|
|
|
|
|
|
<H2><A NAME="ss7.3">7.3</A> <A HREF="#toc7.3">Generic nested scopes</A>
|
|
</H2>
|
|
|
|
|
|
<P>A nested scoped for generic use is started with <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE> and closed with <CODE>
|
|
<A HREF="#.ENDSCOPE">.ENDSCOPE</A></CODE>.
|
|
The scope can have a name, in which case it is accessible from the outside by
|
|
using
|
|
<A HREF="#scopesyntax">explicit scopes</A>. 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.</P>
|
|
<P>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:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope outer
|
|
foo = 2
|
|
.scope inner
|
|
lda #foo
|
|
foo = 3
|
|
.endscope
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In the example above, the <CODE>lda</CODE> instruction will load the value 3 into the
|
|
accumulator, because <CODE>foo</CODE> is redefined in the scope. However:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope outer
|
|
foo = $1234
|
|
.scope inner
|
|
lda foo,x
|
|
foo = $12
|
|
.endscope
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Here, <CODE>lda</CODE> will still load from <CODE>$12,x</CODE>, but since it is unknown to the
|
|
assembler that <CODE>foo</CODE> 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:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope outer
|
|
foo = $12
|
|
.scope inner
|
|
lda foo,x
|
|
foo = $1234
|
|
.endscope
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In this case, when the assembler sees the symbol <CODE>foo</CODE> in the <CODE>lda</CODE>
|
|
instruction, it will search for an already defined symbol <CODE>foo</CODE>. It will
|
|
find <CODE>foo</CODE> in scope <CODE>outer</CODE>, and a close look reveals that it is a
|
|
zeropage symbol. So the assembler will use zeropage addressing mode. If
|
|
<CODE>foo</CODE> is redefined later in scope <CODE>inner</CODE>, the assembler tries to change
|
|
the address in the <CODE>lda</CODE> instruction already translated, but since the new
|
|
value needs absolute addressing mode, this fails, and an error message "Range
|
|
error" is output.</P>
|
|
<P>Of course the most simple solution for the problem is to move the definition
|
|
of <CODE>foo</CODE> in scope <CODE>inner</CODE> upwards, so it precedes 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:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope outer
|
|
foo = $12
|
|
.scope inner
|
|
lda a:foo,x
|
|
foo = $1234
|
|
.endscope
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>This will cause the <CODE>lda</CODE> instruction to be translated using absolute
|
|
addressing mode, which means changing the symbol reference later does not
|
|
cause any errors.</P>
|
|
|
|
|
|
<H2><A NAME="ss7.4">7.4</A> <A HREF="#toc7.4">Nested procedures</A>
|
|
</H2>
|
|
|
|
|
|
<P>A nested procedure is created by use of <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE>. It
|
|
differs from a <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE> in that it must have a
|
|
name, and a it will introduce a symbol with this name in the enclosing scope.
|
|
So</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.proc foo
|
|
...
|
|
.endproc
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>is actually the same as</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
foo:
|
|
.scope foo
|
|
...
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>This is the reason why a procedure must have a name. If you want a scope
|
|
without a name, use <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE>.</P>
|
|
<P><EM>Note:</EM> As you can see from the example above, scopes and symbols live in
|
|
different namespaces. There can be a symbol named <CODE>foo</CODE> and a scope named
|
|
<CODE>foo</CODE> without any conflicts (but see the section titled
|
|
<A HREF="#scopesearch">"Scope search order"</A>).</P>
|
|
|
|
|
|
<H2><A NAME="ss7.5">7.5</A> <A HREF="#toc7.5">Structs, unions and enums</A>
|
|
</H2>
|
|
|
|
|
|
<P>Structs, unions and enums are explained in a
|
|
<A HREF="#structs">separate section</A>, I do only cover them here, because if they are declared with a
|
|
name, they open a nested scope, similar to <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE>. 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.</P>
|
|
|
|
|
|
<H2><A NAME="scopesyntax"></A> <A NAME="ss7.6">7.6</A> <A HREF="#toc7.6">Explicit scope specification</A>
|
|
</H2>
|
|
|
|
|
|
<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 (<CODE>::</CODE>) is used to access other scopes:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope foo
|
|
bar: .word 0
|
|
.endscope
|
|
|
|
...
|
|
lda foo::bar ; Access foo in scope bar
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The only way to deny access to a scope from the outside is to declare a scope
|
|
without a name (using the <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE> command).</P>
|
|
<P>A special syntax is used to specify the global scope: If a symbol or scope is
|
|
preceded by the namespace token, the global scope is searched:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
bar = 3
|
|
|
|
.scope foo
|
|
bar = 2
|
|
lda #::bar ; Access the global bar (which is 3)
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="scopesearch"></A> <A NAME="ss7.7">7.7</A> <A HREF="#toc7.7">Scope search order</A>
|
|
</H2>
|
|
|
|
|
|
<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.</P>
|
|
<P>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 <B>not</B> be
|
|
used without a preceding definition. This means that in the following
|
|
example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope foo
|
|
bar = 3
|
|
.endscope
|
|
|
|
.scope outer
|
|
lda #foo::bar ; Will load 3, not 2!
|
|
.scope foo
|
|
bar = 2
|
|
.endscope
|
|
.endscope
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>the reference to the scope <CODE>foo</CODE> will use the global scope, and not the
|
|
local one, because the local one is not visible at the point where it is
|
|
referenced.</P>
|
|
<P>Things get more complex if a complete chain of scopes is specified:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.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
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>When <CODE>outer::inner::bar</CODE> is referenced in the <CODE>lda</CODE> instruction, the
|
|
assembler will first search in the local scope for a scope named <CODE>outer</CODE>.
|
|
Since none is found, the enclosing scope (<CODE>another</CODE>) is checked. There is
|
|
still no scope named <CODE>outer</CODE>, so scope <CODE>foo</CODE> is checked, and finally
|
|
scope <CODE>outer</CODE> is found. Within this scope, <CODE>inner</CODE> is searched, and in
|
|
this scope, the assembler looks for a symbol named <CODE>bar</CODE>.</P>
|
|
<P>Please note that once the anchor scope is found, all following scopes
|
|
(<CODE>inner</CODE> 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 <CODE>outer</CODE> found by the assembler does not contain a
|
|
scope named <CODE>inner</CODE>, this would be an error, even if such a pair does exist
|
|
(one level up in global scope).</P>
|
|
<P>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 <CODE>bar</CODE>, you would have to write:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.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
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="address-sizes"></A> <A NAME="s8">8.</A> <A HREF="#toc8">Address sizes and memory models</A></H2>
|
|
|
|
|
|
|
|
<H2><A NAME="ss8.1">8.1</A> <A HREF="#toc8.1">Address sizes</A>
|
|
</H2>
|
|
|
|
|
|
<P>ca65 assigns each segment and each symbol an address size. This is true, even
|
|
if the symbol is not used as an address. You may also think of a value range
|
|
of the symbol instead of an address size.</P>
|
|
<P>Possible address sizes are:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>Zeropage or direct (8 bits)</LI>
|
|
<LI>Absolute (16 bits)</LI>
|
|
<LI>Far (24 bits)</LI>
|
|
<LI>Long (32 bits)</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Since the assembler uses default address sizes for the segments and symbols,
|
|
it is usually not necessary to override the default behaviour. In cases, where
|
|
it is necessary, the following keywords may be used to specify address sizes:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>DIRECT, ZEROPAGE or ZP for zeropage addressing (8 bits).</LI>
|
|
<LI>ABSOLUTE, ABS or NEAR for absolute addressing (16 bits).</LI>
|
|
<LI>FAR for far addressing (24 bits).</LI>
|
|
<LI>LONG or DWORD for long addressing (32 bits).</LI>
|
|
</UL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss8.2">8.2</A> <A HREF="#toc8.2">Address sizes of segments</A>
|
|
</H2>
|
|
|
|
|
|
<P>The assembler assigns an address size to each segment. Since the
|
|
representation of a label within this segment is "segment start + offset",
|
|
labels will inherit the address size of the segment they are declared in.</P>
|
|
<P>The address size of a segment may be changed, by using an optional address
|
|
size modifier. See the <CODE>
|
|
<A HREF="#.SEGMENT">segment directive</A></CODE> for
|
|
an explanation on how this is done.</P>
|
|
|
|
|
|
<H2><A NAME="ss8.3">8.3</A> <A HREF="#toc8.3">Address sizes of symbols</A>
|
|
</H2>
|
|
|
|
|
|
<P>The address size of a symbol can be specified with a prefix:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>z: zeropage addressing (8 bits).</LI>
|
|
<LI>a: absolute addressing (16 bits).</LI>
|
|
<LI>f: far addressing (24 bits).</LI>
|
|
</UL>
|
|
</P>
|
|
<P>The zeropage addressing override can be used to ensure the use of optimal
|
|
zeropage instructions, or correct cases where the size isn't yet known
|
|
due to the single-pass assembly model.</P>
|
|
<P>The larger addressing overrides can be used to promote a smaller address
|
|
to absolute or far addressing, instead of being automatically fit into
|
|
a smaller addressing type.</P>
|
|
|
|
|
|
<H2><A NAME="ss8.4">8.4</A> <A HREF="#toc8.4">Memory models</A>
|
|
</H2>
|
|
|
|
|
|
<P>The default address size of a segment depends on the memory model used. Since
|
|
labels inherit the address size from the segment they are declared in,
|
|
changing the memory model is an easy way to change the address size of many
|
|
symbols at once.</P>
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="pseudo-variables"></A> <A NAME="s9">9.</A> <A HREF="#toc9">Pseudo variables</A></H2>
|
|
|
|
|
|
<P>Pseudo variables are readable in all cases, and in some special cases also
|
|
writable.</P>
|
|
|
|
<H2><A NAME="*"></A> <A NAME="ss9.1">9.1</A> <A HREF="#toc9.1"><CODE>*</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will return the program counter at the start
|
|
of the current input line.</P>
|
|
<P>Assignment to this variable is possible when <CODE>
|
|
<A HREF="#.FEATURE">.FEATURE pc_assignment</A></CODE> is used. Note: You should not use
|
|
assignments to <CODE>*</CODE>, use <CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> instead.</P>
|
|
|
|
|
|
<H2><A NAME=".ASIZE"></A> <A NAME="ss9.2">9.2</A> <A HREF="#toc9.2"><CODE>.ASIZE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will return the current size of the
|
|
Accumulator in bits.</P>
|
|
<P>For the 65816 instruction set .ASIZE will return either 8 or 16, depending
|
|
on the current size of the operand in immediate accu addressing mode.</P>
|
|
<P>For all other CPU instruction sets, .ASIZE will always return 8.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Reverse Subtract with Accumulator
|
|
; A = memory - A
|
|
.macro rsb param
|
|
.if .asize = 8
|
|
eor #$ff
|
|
.else
|
|
eor #$ffff
|
|
.endif
|
|
sec
|
|
adc param
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ISIZE">.ISIZE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".CPU"></A> <A NAME="ss9.3">9.3</A> <A HREF="#toc9.3"><CODE>.CPU</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will give a constant integer value that
|
|
tells which CPU is currently enabled. It can also tell which instruction
|
|
set the CPU is able to translate. The value read from the pseudo variable
|
|
should be further examined by using one of the constants defined by the
|
|
"cpu" macro package (see <CODE>
|
|
<A HREF="#.MACPACK">.MACPACK</A></CODE>).</P>
|
|
<P>It may be used to replace the .IFPxx pseudo instructions or to construct
|
|
even more complex expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macpack cpu
|
|
.if (.cpu .bitand CPU_ISET_65816)
|
|
phx
|
|
phy
|
|
.else
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".ISIZE"></A> <A NAME="ss9.4">9.4</A> <A HREF="#toc9.4"><CODE>.ISIZE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will return the current size of the Index
|
|
register in bits.</P>
|
|
<P>For the 65816 instruction set .ISIZE will return either 8 or 16, depending
|
|
on the current size of the operand in immediate index addressing mode.</P>
|
|
<P>For all other CPU instruction sets, .ISIZE will always return 8.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ASIZE">.ASIZE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PARAMCOUNT"></A> <A NAME="ss9.5">9.5</A> <A HREF="#toc9.5"><CODE>.PARAMCOUNT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This builtin pseudo variable is only available in macros. It is replaced by
|
|
the actual number of parameters that were given in the macro invocation.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro foo arg1, arg2, arg3
|
|
.if .paramcount <> 3
|
|
.error "Too few parameters for macro foo"
|
|
.endif
|
|
...
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".TIME"></A> <A NAME="ss9.6">9.6</A> <A HREF="#toc9.6"><CODE>.TIME</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will give a constant integer value that
|
|
represents the current time in POSIX standard (as seconds since the
|
|
Epoch).</P>
|
|
<P>It may be used to encode the time of translation somewhere in the created
|
|
code.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.dword .time ; Place time here
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".VERSION"></A> <A NAME="ss9.7">9.7</A> <A HREF="#toc9.7"><CODE>.VERSION</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reading this pseudo variable will give the assembler version according to
|
|
the following formula:</P>
|
|
<P><CODE>(VER_MAJOR * 0x100) + VER_MINOR</CODE></P>
|
|
<P>The upper 8 bits are the major-, the lower 8 bits are the minor version.</P>
|
|
<P>Example:</P>
|
|
<P>For example, version 47.11 of the assembler would have this macro defined as
|
|
<CODE>0x2f0b</CODE>.</P>
|
|
<P>Note: until 2.19 this pseudo variable was defined as <CODE>(VER_MAJOR * 0x100) + VER_MINOR * 0x10</CODE> -
|
|
which resulted in broken values starting at version 2.16 of the assembler. For
|
|
this reason the value of this pseudo variable is considered purely informal - you should
|
|
not use it to check for a specific assembler version and use different code
|
|
according to the detected version - please update your code to work with the
|
|
recent version of the assembler instead (There is very little reason to not use
|
|
the most recent version - and even less to support older versions in your code).</P>
|
|
|
|
<H2><A NAME="pseudo-functions"></A> <A NAME="s10">10.</A> <A HREF="#toc10">Pseudo functions</A></H2>
|
|
|
|
|
|
<P>Pseudo functions expect their arguments in parentheses, and they have a result,
|
|
either a string or an expression value.</P>
|
|
|
|
|
|
<H2><A NAME=".ADDRSIZE"></A> <A NAME="ss10.1">10.1</A> <A HREF="#toc10.1"><CODE>.ADDRSIZE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The <CODE>.ADDRSIZE</CODE> function is used to return the internal address size
|
|
associated with a symbol. This can be helpful in macros when knowing the address
|
|
size of a symbol can help with custom instructions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro myLDA foo
|
|
.if .ADDRSIZE(foo) = 1
|
|
;do custom command based on zeropage addressing:
|
|
.byte 0A5h, foo
|
|
.elseif .ADDRSIZE(foo) = 2
|
|
;do custom command based on absolute addressing:
|
|
.byte 0ADh
|
|
.word foo
|
|
.elseif .ADDRSIZE(foo) = 0
|
|
; no address size defined for this symbol:
|
|
.out .sprintf("Error, address size unknown for symbol %s", .string(foo))
|
|
.endif
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".BANK"></A> <A NAME="ss10.2">10.2</A> <A HREF="#toc10.2"><CODE>.BANK</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The <CODE>.BANK</CODE> function is used to support systems with banked memory. The
|
|
argument is an expression with exactly one segment reference -- usually a
|
|
label. The function result is the value of the <CODE>bank</CODE> attribute assigned
|
|
to the run memory area of the segment. Please see the linker documentation
|
|
for more information about memory areas and their attributes.</P>
|
|
<P>The value of <CODE>.BANK</CODE> can be used to switch memory so that a memory bank
|
|
containing specific data is available.</P>
|
|
<P>The <CODE>bank</CODE> attribute is a 32-bit integer, and so is the result of the
|
|
<CODE>.BANK</CODE> function. You will have to use <CODE>
|
|
<A HREF="#.LOBYTE">.LOBYTE</A></CODE> or similar functions to address just part of it.</P>
|
|
<P>Please note that <CODE>.BANK</CODE> always will get evaluated in the link stage, so
|
|
an expression containing <CODE>.BANK</CODE> never can be used where a constant, known
|
|
result is expected (for example, with <CODE>.RES</CODE>).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "BANK1"
|
|
.proc banked_func_1
|
|
...
|
|
.endproc
|
|
|
|
.segment "BANK2"
|
|
.proc banked_func_2
|
|
...
|
|
.endproc
|
|
|
|
.proc bank_table
|
|
.addr banked_func_1
|
|
.byte <.BANK (banked_func_1)
|
|
|
|
.addr banked_func_2
|
|
.byte <.BANK (banked_func_2)
|
|
.endproc
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME=".BANKBYTE"></A> <A NAME="ss10.3">10.3</A> <A HREF="#toc10.3"><CODE>.BANKBYTE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function returns the bank byte (that is, bits 16-23) of its argument.
|
|
It works identical to the '^' operator.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.HIBYTE">.HIBYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.LOBYTE">.LOBYTE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".BLANK"></A> <A NAME="ss10.4">10.4</A> <A HREF="#toc10.4"><CODE>.BLANK</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function evaluates its argument in parentheses 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.</P>
|
|
<P>As an example, the <CODE>.IFBLANK</CODE> statement may be replaced by</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if .blank({arg})
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME=".CONCAT"></A> <A NAME="ss10.5">10.5</A> <A HREF="#toc10.5"><CODE>.CONCAT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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 <CODE>.STRING</CODE> builtin function. The function may
|
|
be used in any case where a string constant is expected.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.include .concat ("myheader", ".", "inc")
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>This is the same as the command</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.include "myheader.inc"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".CONST"></A> <A NAME="ss10.6">10.6</A> <A HREF="#toc10.6"><CODE>.CONST</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function evaluates its argument in parentheses 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</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if .const(a + 3)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".DEFINED"></A> <A NAME="ss10.7">10.7</A> <A HREF="#toc10.7"><CODE>.DEF, .DEFINED</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function expects an identifier as argument in parentheses.
|
|
The argument is evaluated, and the function yields "true" if the identifier
|
|
is a symbol that already is defined somewhere in the source file up to the
|
|
current position. Otherwise, the function yields false. As an example, the
|
|
<CODE>
|
|
<A HREF="#.IFDEF">.IFDEF</A></CODE> statement may be replaced by</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if .defined(a)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".DEFINEDMACRO"></A> <A NAME="ss10.8">10.8</A> <A HREF="#toc10.8"><CODE>.DEFINEDMACRO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function expects an identifier as argument in parentheses.
|
|
The argument is evaluated, and the function yields "true" if the identifier
|
|
already has been defined as the name of a macro. Otherwise, the function yields
|
|
false. Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro add foo
|
|
clc
|
|
adc foo
|
|
.endmacro
|
|
|
|
.if .definedmacro(add)
|
|
add #$01
|
|
.else
|
|
clc
|
|
adc #$01
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".HIBYTE"></A> <A NAME="ss10.9">10.9</A> <A HREF="#toc10.9"><CODE>.HIBYTE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function returns the high byte (that is, bits 8-15) of its argument.
|
|
It works identical to the '>' operator.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.LOBYTE">.LOBYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.BANKBYTE">.BANKBYTE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".HIWORD"></A> <A NAME="ss10.10">10.10</A> <A HREF="#toc10.10"><CODE>.HIWORD</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function returns the high word (that is, bits 16-31) of its argument.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.LOWORD">.LOWORD</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IDENT"></A> <A NAME="ss10.11">10.11</A> <A HREF="#toc10.11"><CODE>.IDENT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function expects a string as its argument, and converts this argument
|
|
into an identifier. If the string starts with the current <CODE>
|
|
<A HREF="#.LOCALCHAR">.LOCALCHAR</A></CODE>, it will be converted into a cheap local
|
|
identifier, otherwise it will be converted into a normal identifier.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro makelabel arg1, arg2
|
|
.ident (.concat (arg1, arg2)):
|
|
.endmacro
|
|
|
|
makelabel "foo", "bar"
|
|
|
|
.word foobar ; Valid label
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".ISMNEMONIC"></A> <A NAME="ss10.12">10.12</A> <A HREF="#toc10.12"><CODE>.ISMNEM, .ISMNEMONIC</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function expects an identifier as argument in parentheses.
|
|
The argument is evaluated, and the function yields "true" if the identifier
|
|
is defined as an instruction mnemonic that is recognized by the assembler.
|
|
Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if .not .ismnemonic(ina)
|
|
.macro ina
|
|
clc
|
|
adc #$01
|
|
.endmacro
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".LEFT"></A> <A NAME="ss10.13">10.13</A> <A HREF="#toc10.13"><CODE>.LEFT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. Extracts the left part of a given token list.</P>
|
|
<P>Syntax:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.LEFT (<int expr>, <token list>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>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).</P>
|
|
<P>Example:</P>
|
|
<P>To check in a macro if the given argument has a '#' as first token
|
|
(immediate addressing mode), use something like this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro ldax arg
|
|
...
|
|
.if (.match (.left (1, {arg}), #))
|
|
|
|
; ldax called with immediate operand
|
|
...
|
|
|
|
.endif
|
|
...
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.MID">.MID</A></CODE> and <CODE>
|
|
<A HREF="#.RIGHT">.RIGHT</A></CODE> builtin functions.</P>
|
|
|
|
|
|
<H2><A NAME=".LOBYTE"></A> <A NAME="ss10.14">10.14</A> <A HREF="#toc10.14"><CODE>.LOBYTE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function returns the low byte (that is, bits 0-7) of its argument.
|
|
It works identical to the '<' operator.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.HIBYTE">.HIBYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.BANKBYTE">.BANKBYTE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".LOWORD"></A> <A NAME="ss10.15">10.15</A> <A HREF="#toc10.15"><CODE>.LOWORD</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>The function returns the low word (that is, bits 0-15) of its argument.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.HIWORD">.HIWORD</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".MATCH"></A> <A NAME="ss10.16">10.16</A> <A HREF="#toc10.16"><CODE>.MATCH</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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.</P>
|
|
<P>The syntax is</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.MATCH(<token list #1>, <token list #2>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Both token list may contain arbitrary tokens with the exception of the
|
|
terminator token (comma resp. right parenthesis) and</P>
|
|
<P>
|
|
<UL>
|
|
<LI>end-of-line</LI>
|
|
<LI>end-of-file</LI>
|
|
</UL>
|
|
</P>
|
|
<P>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.</P>
|
|
<P>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
|
|
<EM>and</EM> token attributes, use the <CODE>
|
|
<A HREF="#.XMATCH">.XMATCH</A></CODE> function.</P>
|
|
<P>Example:</P>
|
|
<P>Assume the macro <CODE>ASR</CODE>, 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 <CODE>ROL</CODE> and
|
|
<CODE>ROR</CODE>. We will use the <CODE>
|
|
<A HREF="#.MATCH">.MATCH</A></CODE> function
|
|
to check for this and print and error for invalid calls.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.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
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The macro will only accept no arguments, or one argument that must be the
|
|
reserved keyword "A".</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.XMATCH">.XMATCH</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".MAX"></A> <A NAME="ss10.17">10.17</A> <A HREF="#toc10.17"><CODE>.MAX</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The result is the larger of two values.</P>
|
|
<P>The syntax is</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.MAX (<value #1>, <value #2>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Reserve space for the larger of two data blocks
|
|
savearea: .res .max (.sizeof (foo), .sizeof (bar))
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.MIN">.MIN</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".MID"></A> <A NAME="ss10.18">10.18</A> <A HREF="#toc10.18"><CODE>.MID</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. Takes a starting index, a count and a token list as
|
|
arguments. Will return part of the token list.</P>
|
|
<P>Syntax:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.MID (<int expr>, <int expr>, <token list>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>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).</P>
|
|
<P>Example:</P>
|
|
<P>To check in a macro if the given argument has a '<CODE>#</CODE>' as first token
|
|
(immediate addressing mode), use something like this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro ldax arg
|
|
...
|
|
.if (.match (.mid (0, 1, {arg}), #))
|
|
|
|
; ldax called with immediate operand
|
|
...
|
|
|
|
.endif
|
|
...
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.LEFT">.LEFT</A></CODE> and <CODE>
|
|
<A HREF="#.RIGHT">.RIGHT</A></CODE> builtin functions.</P>
|
|
|
|
|
|
<H2><A NAME=".MIN"></A> <A NAME="ss10.19">10.19</A> <A HREF="#toc10.19"><CODE>.MIN</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The result is the smaller of two values.</P>
|
|
<P>The syntax is</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.MIN (<value #1>, <value #2>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Reserve space for some data, but 256 bytes maximum
|
|
savearea: .res .min (.sizeof (foo), 256)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.MAX">.MAX</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".REFERENCED"></A> <A NAME="ss10.20">10.20</A> <A HREF="#toc10.20"><CODE>.REF, .REFERENCED</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function expects an identifier as argument in parentheses.
|
|
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 <CODE>
|
|
<A HREF="#.IFREF">.IFREF</A></CODE> statement may be replaced by</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if .referenced(a)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.DEFINED">.DEFINED</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".RIGHT"></A> <A NAME="ss10.21">10.21</A> <A HREF="#toc10.21"><CODE>.RIGHT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. Extracts the right part of a given token list.</P>
|
|
<P>Syntax:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.RIGHT (<int expr>, <token list>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>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).</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.LEFT">.LEFT</A></CODE> and <CODE>
|
|
<A HREF="#.MID">.MID</A></CODE> builtin functions.</P>
|
|
|
|
|
|
<H2><A NAME=".SIZEOF"></A> <A NAME="ss10.22">10.22</A> <A HREF="#toc10.22"><CODE>.SIZEOF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P><CODE>.SIZEOF()</CODE> is a pseudo function that returns the size of its argument.
|
|
The argument can be a struct/union, a struct member, a scope/procedure, or a
|
|
label. In the 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.</P>
|
|
<P>Please note that a symbol or scope must exist before it can be used together
|
|
with <CODE>.SIZEOF()</CODE> (that may get relaxed later, but always will 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, then the scope is
|
|
chosen over the symbol.</P>
|
|
<P>After the following code:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Point ; Struct size = 4
|
|
xcoord .word
|
|
ycoord .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
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>
|
|
<DL>
|
|
<DT><B><CODE>.sizeof(Point)</CODE></B><DD>
|
|
<P>will have the value 4, because this is the size of struct <CODE>Point</CODE>.</P>
|
|
|
|
<DT><B><CODE>.sizeof(Point::xcoord)</CODE></B><DD>
|
|
<P>will have the value 2, because this is the size of the member <CODE>xcoord</CODE>
|
|
in struct <CODE>Point</CODE>.</P>
|
|
|
|
<DT><B><CODE>.sizeof(P)</CODE></B><DD>
|
|
<P>will have the value 4, this is the size of the data declared on the same
|
|
source line as the label <CODE>P</CODE>, which is in the same segment that <CODE>P</CODE>
|
|
is relative to.</P>
|
|
|
|
<DT><B><CODE>.sizeof(@P)</CODE></B><DD>
|
|
<P>will have the value 4, see above. The example demonstrates that <CODE>.SIZEOF</CODE>
|
|
does also work for cheap local symbols.</P>
|
|
|
|
<DT><B><CODE>.sizeof(Code)</CODE></B><DD>
|
|
<P>will have the value 3, since this is amount of data emitted into the code
|
|
segment, the segment that was active when <CODE>Code</CODE> was entered. Note that
|
|
this value includes the amount of data emitted in child scopes (in this
|
|
case <CODE>Code::Inner</CODE>).</P>
|
|
|
|
<DT><B><CODE>.sizeof(Code::Inner)</CODE></B><DD>
|
|
<P>will have the value 1 as expected.</P>
|
|
|
|
<DT><B><CODE>.sizeof(Data)</CODE></B><DD>
|
|
<P>will have the value 0. Data is emitted within the scope <CODE>Data</CODE>, but since
|
|
the segment is switched after entry, this data is emitted into another
|
|
segment.</P>
|
|
</DL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".SPRINTF"></A> <A NAME="ss10.23">10.23</A> <A HREF="#toc10.23"><CODE>.SPRINTF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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 <CODE>printf</CODE> function. Missing things
|
|
are: Length modifiers, variable width.</P>
|
|
<P>The result of the function is a string.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
num = 3
|
|
|
|
; Generate an identifier:
|
|
.ident (.sprintf ("%s%03d", "label", num)):
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".STRAT"></A> <A NAME="ss10.24">10.24</A> <A HREF="#toc10.24"><CODE>.STRAT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro M Arg
|
|
; Check if the argument string starts with '#'
|
|
.if (.strat (Arg, 0) = '#')
|
|
...
|
|
.endif
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".STRING"></A> <A NAME="ss10.25">10.25</A> <A HREF="#toc10.25"><CODE>.STRING</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function accepts an argument in parentheses and converts
|
|
this argument into a string constant. The argument may be an identifier, or
|
|
a constant numeric value.</P>
|
|
<P>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.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Emulate other assemblers:
|
|
.macro section name
|
|
.segment .string(name)
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".STRLEN"></A> <A NAME="ss10.26">10.26</A> <A HREF="#toc10.26"><CODE>.STRLEN</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function accepts a string argument in parentheses and
|
|
evaluates to the length of the string.</P>
|
|
<P>Example:</P>
|
|
<P>The following macro encodes a string as a pascal style string with
|
|
a leading length byte.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro PString Arg
|
|
.byte .strlen(Arg), Arg
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".TCOUNT"></A> <A NAME="ss10.27">10.27</A> <A HREF="#toc10.27"><CODE>.TCOUNT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Builtin function. The function accepts a token list in parentheses. 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).</P>
|
|
<P>Example:</P>
|
|
<P>The <CODE>ldax</CODE> 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:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.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
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".XMATCH"></A> <A NAME="ss10.28">10.28</A> <A HREF="#toc10.28"><CODE>.XMATCH</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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.</P>
|
|
<P>The syntax is</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.XMATCH(<token list #1>, <token list #2>)
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Both token list may contain arbitrary tokens with the exception of the
|
|
terminator token (comma resp. right parenthesis) and</P>
|
|
<P>
|
|
<UL>
|
|
<LI>end-of-line</LI>
|
|
<LI>end-of-file</LI>
|
|
</UL>
|
|
</P>
|
|
<P>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.</P>
|
|
<P>The function compares tokens <EM>and</EM> token values. If you need a function
|
|
that just compares the type of tokens, have a look at the <CODE>
|
|
<A HREF="#.MATCH">.MATCH</A></CODE> function.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.MATCH">.MATCH</A></CODE></P>
|
|
|
|
|
|
|
|
<H2><A NAME="control-commands"></A> <A NAME="s11">11.</A> <A HREF="#toc11">Control commands</A></H2>
|
|
|
|
|
|
<P>Here's a list of all control commands and a description, what they do:</P>
|
|
|
|
|
|
<H2><A NAME=".A16"></A> <A NAME="ss11.1">11.1</A> <A HREF="#toc11.1"><CODE>.A16</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Valid only in 65816 mode. Assume the accumulator is 16 bit.</P>
|
|
<P>Note: This command will not emit any code, it will tell the assembler to
|
|
create 16 bit operands for immediate accumulator addressing mode.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".A8"></A> <A NAME="ss11.2">11.2</A> <A HREF="#toc11.2"><CODE>.A8</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Valid only in 65816 mode. Assume the accumulator is 8 bit.</P>
|
|
<P>Note: This command will not emit any code, it will tell the assembler to
|
|
create 8 bit operands for immediate accu addressing mode.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".ADDR"></A> <A NAME="ss11.3">11.3</A> <A HREF="#toc11.3"><CODE>.ADDR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define word sized data. In 6502 mode, this is an alias for <CODE>.WORD</CODE> and
|
|
may be used for better readability if the data words are address values. In
|
|
65816 mode, the address is forced to be 16 bit wide to fit into the current
|
|
segment. See also <CODE>
|
|
<A HREF="#.FARADDR">.FARADDR</A></CODE>. The command
|
|
must be followed by a sequence of (not necessarily constant) expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.addr $0D00, $AF13, _Clear
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.FARADDR">.FARADDR</A></CODE>, <CODE>
|
|
<A HREF="#.WORD">.WORD</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".ALIGN"></A> <A NAME="ss11.4">11.4</A> <A HREF="#toc11.4"><CODE>.ALIGN</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Align data to a given boundary. The command expects a constant integer
|
|
argument in the range 1 ... 65536, plus an optional second argument
|
|
in byte range. If there is a second argument, it is used as fill value,
|
|
otherwise the value defined in the linker configuration file is used
|
|
(the default for this value is zero).</P>
|
|
<P><CODE>.ALIGN</CODE> will insert fill bytes, and the number of fill bytes depend of
|
|
the final address of the segment. <CODE>.ALIGN</CODE> cannot insert a variable
|
|
number of bytes, since that would break address calculations within the
|
|
module. So each <CODE>.ALIGN</CODE> expects the segment to be aligned to a multiple
|
|
of the alignment, because that allows the number of fill bytes to be
|
|
calculated in advance by the assembler. You are therefore required to
|
|
specify a matching alignment for the segment in the linker config. The
|
|
linker will output a warning if the alignment of the segment is less than
|
|
what is necessary to have a correct alignment in the object file.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.align 256
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Some unexpected behaviour might occur if there are multiple <CODE>.ALIGN</CODE>
|
|
commands with different arguments. To allow the assembler to calculate the
|
|
number of fill bytes in advance, the alignment of the segment must be a
|
|
multiple of each of the alignment factors. This may result in unexpectedly
|
|
large alignments for the segment within the module.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.align 15
|
|
.byte 15
|
|
.align 18
|
|
.byte 18
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>For the assembler to be able to align correctly, the segment must be aligned
|
|
to the least common multiple of 15 and 18 which is 90. The assembler will
|
|
calculate this automatically and will mark the segment with this value.</P>
|
|
<P>Unfortunately, the combined alignment may get rather large without the user
|
|
knowing about it, wasting space in the final executable. If we add another
|
|
alignment to the example above</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.align 15
|
|
.byte 15
|
|
.align 18
|
|
.byte 18
|
|
.align 251
|
|
.byte 0
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>the assembler will force a segment alignment to the least common multiple of
|
|
15, 18 and 251 - which is 22590. To protect the user against errors, when the
|
|
combined alignment is larger than the explicitly requested alignments,
|
|
the assembler will issue a warning if it also exceeds 256. The command line
|
|
option <CODE>
|
|
<A HREF="#option--large-alignment">--large-alignment</A></CODE>
|
|
will disable this warning.</P>
|
|
<P>Please note that with only alignments that are a power of two, a warning will
|
|
never occur, because the least common multiple of powers to the same base is
|
|
always simply the larger one.</P>
|
|
|
|
|
|
|
|
<H2><A NAME=".ASCIIZ"></A> <A NAME="ss11.5">11.5</A> <A HREF="#toc11.5"><CODE>.ASCIIZ</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define a string with a trailing zero.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
Msg: .asciiz "Hello world"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>This will put the string "Hello world" followed by a binary zero into
|
|
the current segment. There may be more strings separated by commas, but
|
|
the binary zero is only appended once (after the last one). Strings will
|
|
be translated using the current character mapping definition.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE>,<CODE>
|
|
<A HREF="#.CHARMAP">.CHARMAP</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.LITERAL">.LITERAL</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".ASSERT"></A> <A NAME="ss11.6">11.6</A> <A HREF="#toc11.6"><CODE>.ASSERT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Add an assertion. The command is followed by an expression, an action
|
|
specifier, and an optional message that is output in case the assertion
|
|
fails. If no message was given, the string "Assertion failed" is used. The
|
|
action specifier may be one of <CODE>warning</CODE>, <CODE>error</CODE>, <CODE>ldwarning</CODE> or
|
|
<CODE>lderror</CODE>. In the former two cases, the assertion is evaluated by the
|
|
assembler if possible, and in any case, it's also passed to the linker in
|
|
the object file (if one is generated). The linker will then evaluate the
|
|
expression when segment placement has been done.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.assert * = $8000, error, "Code not at $8000"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The example assertion will check that the current location is at $8000,
|
|
when the output file is written, and abort with an error if this is not
|
|
the case. More complex expressions are possible. The action specifier
|
|
<CODE>warning</CODE> outputs a warning, while the <CODE>error</CODE> specifier outputs
|
|
an error message. In the latter case, generation of the output file is
|
|
suppressed in both the assembler and linker.</P>
|
|
|
|
|
|
<H2><A NAME=".AUTOIMPORT"></A> <A NAME="ss11.7">11.7</A> <A HREF="#toc11.7"><CODE>.AUTOIMPORT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Is followed by a plus or a minus character. When switched on (using a
|
|
+), undefined symbols are automatically marked as import instead of
|
|
giving errors. When switched off (which is the default so this does not
|
|
make much sense), this does not happen and an error message is
|
|
displayed. The state of the autoimport flag is evaluated when the
|
|
complete source was translated, before outputting actual code, so it is
|
|
<EM>not</EM> possible to switch this feature on or off for separate sections
|
|
of code. The last setting is used for all symbols.</P>
|
|
<P>You should probably not use this switch because it delays error
|
|
messages about undefined symbols until the link stage. The cc65
|
|
compiler (which is supposed to produce correct assembler code in all
|
|
circumstances, something which is not true for most assembler
|
|
programmers) will insert this command to avoid importing each and every
|
|
routine from the runtime library.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.autoimport + ; Switch on auto import
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
<H2><A NAME=".BANKBYTES"></A> <A NAME="ss11.8">11.8</A> <A HREF="#toc11.8"><CODE>.BANKBYTES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define byte sized data by extracting only the bank byte (that is, bits 16-23) from
|
|
each expression. This is equivalent to <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE> with
|
|
the operator '^' prepended to each expression in its list.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define MyTable TableItem0, TableItem1, TableItem2, TableItem3
|
|
|
|
TableLookupLo: .lobytes MyTable
|
|
TableLookupHi: .hibytes MyTable
|
|
TableLookupBank: .bankbytes MyTable
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>which is equivalent to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3
|
|
TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3
|
|
TableLookupBank: .byte ^TableItem0, ^TableItem1, ^TableItem2, ^TableItem3
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.HIBYTES">.HIBYTES</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.LOBYTES">.LOBYTES</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".BSS"></A> <A NAME="ss11.9">11.9</A> <A HREF="#toc11.9"><CODE>.BSS</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to the BSS segment. The name of the BSS segment is always "BSS",
|
|
so this is a shortcut for</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "BSS"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.SEGMENT">.SEGMENT</A></CODE> command.</P>
|
|
|
|
|
|
<H2><A NAME=".BYTE"></A> <A NAME="ss11.10">11.10</A> <A HREF="#toc11.10"><CODE>.BYT, .BYTE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define byte sized data. Must be followed by a sequence of (byte ranged)
|
|
expressions or strings. Strings will be translated using the current
|
|
character mapping definition.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.byte "Hello "
|
|
.byt "world", $0D, $00
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ASCIIZ">.ASCIIZ</A></CODE>,<CODE>
|
|
<A HREF="#.CHARMAP">.CHARMAP</A></CODE>
|
|
<CODE>
|
|
<A HREF="#.LITERAL">.LITERAL</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".CASE"></A> <A NAME="ss11.11">11.11</A> <A HREF="#toc11.11"><CODE>.CASE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch on or off case sensitivity on identifiers. The default is off
|
|
(that is, identifiers are case sensitive), but may be changed by the
|
|
-i switch on the command line.
|
|
The command can be followed by a '+' or '-' character to switch the
|
|
option on or off respectively.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.case - ; Identifiers are not case sensitive
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".CHARMAP"></A> <A NAME="ss11.12">11.12</A> <A HREF="#toc11.12"><CODE>.CHARMAP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Apply a custom mapping for characters for the commands <CODE>
|
|
<A HREF="#.ASCIIZ">.ASCIIZ</A></CODE> and <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE>. The command
|
|
is followed by two numbers. The first one is the index of the source character
|
|
(range 0..255);
|
|
the second one is the mapping (range 0..255). The mapping applies to all
|
|
character and string constants <EM>when</EM> they generate output; and, overrides
|
|
a mapping table specified with the <CODE>
|
|
<A HREF="#option-t">-t</A></CODE>
|
|
command line switch.</P>
|
|
<P>Example:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.charmap $41, $61 ; Map 'A' to 'a'
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".CODE"></A> <A NAME="ss11.13">11.13</A> <A HREF="#toc11.13"><CODE>.CODE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to the CODE segment. The name of the CODE segment is always
|
|
"CODE", so this is a shortcut for</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "CODE"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.SEGMENT">.SEGMENT</A></CODE> command.</P>
|
|
|
|
|
|
<H2><A NAME=".CONDES"></A> <A NAME="ss11.14">11.14</A> <A HREF="#toc11.14"><CODE>.CONDES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Export a symbol and mark it in a special way. The linker is able to build
|
|
tables of all such symbols. This may be used to automatically create a list
|
|
of functions needed to initialize linked library modules.</P>
|
|
<P>Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol with
|
|
<CODE>.CONDES</CODE> does nothing by itself.</P>
|
|
<P>All symbols are exported as an absolute (16 bit) symbol. You don't need to
|
|
use an additional <CODE>
|
|
<A HREF="#.EXPORT">.EXPORT</A></CODE> statement, this
|
|
is implied by <CODE>.CONDES</CODE>.</P>
|
|
<P><CODE>.CONDES</CODE> is followed by the type, which may be <CODE>constructor</CODE>,
|
|
<CODE>destructor</CODE> or a numeric value between 0 and 6 (where 0 is the same as
|
|
specifying <CODE>constructor</CODE> and 1 is equal to specifying <CODE>destructor</CODE>).
|
|
The <CODE>
|
|
<A HREF="#.CONSTRUCTOR">.CONSTRUCTOR</A></CODE>, <CODE>
|
|
<A HREF="#.DESTRUCTOR">.DESTRUCTOR</A></CODE> and <CODE>
|
|
<A HREF="#.INTERRUPTOR">.INTERRUPTOR</A></CODE> commands are actually shortcuts for <CODE>.CONDES</CODE>
|
|
with a type of <CODE>constructor</CODE> resp. <CODE>destructor</CODE> or <CODE>interruptor</CODE>.</P>
|
|
<P>After the type, an optional priority may be specified. Higher numeric values
|
|
mean higher priority. If no priority is given, the default priority of 7 is
|
|
used. Be careful when assigning priorities to your own module constructors
|
|
so they won't interfere with the ones in the cc65 library.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.condes ModuleInit, constructor
|
|
.condes ModInit, 0, 16
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See the <CODE>
|
|
<A HREF="#.CONSTRUCTOR">.CONSTRUCTOR</A></CODE>, <CODE>
|
|
<A HREF="#.DESTRUCTOR">.DESTRUCTOR</A></CODE> and <CODE>
|
|
<A HREF="#.INTERRUPTOR">.INTERRUPTOR</A></CODE> commands and the separate section
|
|
<A HREF="#condes">Module constructors/destructors</A> explaining the feature in more
|
|
detail.</P>
|
|
|
|
|
|
<H2><A NAME=".CONSTRUCTOR"></A> <A NAME="ss11.15">11.15</A> <A HREF="#toc11.15"><CODE>.CONSTRUCTOR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Export a symbol and mark it as a module constructor. This may be used
|
|
together with the linker to build a table of constructor subroutines that
|
|
are called by the startup code.</P>
|
|
<P>Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol as
|
|
constructor does nothing by itself.</P>
|
|
<P>A constructor is always exported as an absolute (16 bit) symbol. You don't
|
|
need to use an additional <CODE>.export</CODE> statement, this is implied by
|
|
<CODE>.constructor</CODE>. It may have an optional priority that is separated by a
|
|
comma. Higher numeric values mean a higher priority. If no priority is
|
|
given, the default priority of 7 is used. Be careful when assigning
|
|
priorities to your own module constructors so they won't interfere with the
|
|
ones in the cc65 library.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.constructor ModuleInit
|
|
.constructor ModInit, 16
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See the <CODE>
|
|
<A HREF="#.CONDES">.CONDES</A></CODE> and <CODE>
|
|
<A HREF="#.DESTRUCTOR">.DESTRUCTOR</A></CODE> commands and the separate section
|
|
<A HREF="#condes">Module constructors/destructors</A> explaining the
|
|
feature in more detail.</P>
|
|
|
|
|
|
<H2><A NAME=".DATA"></A> <A NAME="ss11.16">11.16</A> <A HREF="#toc11.16"><CODE>.DATA</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to the DATA segment. The name of the DATA segment is always
|
|
"DATA", so this is a shortcut for</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "DATA"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.SEGMENT">.SEGMENT</A></CODE> command.</P>
|
|
|
|
|
|
<H2><A NAME=".DBYT"></A> <A NAME="ss11.17">11.17</A> <A HREF="#toc11.17"><CODE>.DBYT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define word sized data with the hi and lo bytes swapped (use <CODE>.WORD</CODE> to
|
|
create word sized data in native 65XX format). Must be followed by a
|
|
sequence of (word ranged) expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.dbyt $1234, $4512
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>This will emit the bytes</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
$12 $34 $45 $12
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>into the current segment in that order.</P>
|
|
|
|
|
|
<H2><A NAME=".DEBUGINFO"></A> <A NAME="ss11.18">11.18</A> <A HREF="#toc11.18"><CODE>.DEBUGINFO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch on or off debug info generation. The default is off (that is,
|
|
the object file will not contain debug infos), but may be changed by the
|
|
-g switch on the command line.
|
|
The command can be followed by a '+' or '-' character to switch the
|
|
option on or off respectively.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.debuginfo + ; Generate debug info
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".DEFINE"></A> <A NAME="ss11.19">11.19</A> <A HREF="#toc11.19"><CODE>.DEFINE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Start a define style macro definition. The command is followed by an
|
|
identifier (the macro name) and optionally by a list of formal arguments
|
|
in parentheses.</P>
|
|
<P>Please note that <CODE>.DEFINE</CODE> shares most disadvantages with its C
|
|
counterpart, so the general advice is, <B>NOT</B> do use <CODE>.DEFINE</CODE> if you
|
|
don't have to.</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.UNDEFINE">.UNDEFINE</A></CODE> command and
|
|
section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".DELMACRO"></A> <A NAME="ss11.20">11.20</A> <A HREF="#toc11.20"><CODE>.DELMAC, .DELMACRO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Delete a classic macro (defined with <CODE>
|
|
<A HREF="#.MACRO">.MACRO</A></CODE>) . The command is followed by the name of an
|
|
existing macro. Its definition will be deleted together with the name.
|
|
If necessary, another macro with this name may be defined later.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ENDMACRO">.ENDMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.EXITMACRO">.EXITMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.MACRO">.MACRO</A></CODE></P>
|
|
<P>See also section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".DESTRUCTOR"></A> <A NAME="ss11.21">11.21</A> <A HREF="#toc11.21"><CODE>.DESTRUCTOR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Export a symbol and mark it as a module destructor. This may be used
|
|
together with the linker to build a table of destructor subroutines that
|
|
are called by the startup code.</P>
|
|
<P>Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol as
|
|
constructor does nothing by itself.</P>
|
|
<P>A destructor is always exported as an absolute (16 bit) symbol. You don't
|
|
need to use an additional <CODE>.export</CODE> statement, this is implied by
|
|
<CODE>.destructor</CODE>. It may have an optional priority that is separated by a
|
|
comma. Higher numerical values mean a higher priority. If no priority is
|
|
given, the default priority of 7 is used. Be careful when assigning
|
|
priorities to your own module destructors so they won't interfere with the
|
|
ones in the cc65 library.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.destructor ModuleDone
|
|
.destructor ModDone, 16
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See the <CODE>
|
|
<A HREF="#.CONDES">.CONDES</A></CODE> and <CODE>
|
|
<A HREF="#.CONSTRUCTOR">.CONSTRUCTOR</A></CODE> commands and the separate
|
|
section
|
|
<A HREF="#condes">Module constructors/destructors</A> explaining
|
|
the feature in more detail.</P>
|
|
|
|
|
|
<H2><A NAME=".DWORD"></A> <A NAME="ss11.22">11.22</A> <A HREF="#toc11.22"><CODE>.DWORD</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define dword sized data (4 bytes) Must be followed by a sequence of
|
|
expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.dword $12344512, $12FA489
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".ELSE"></A> <A NAME="ss11.23">11.23</A> <A HREF="#toc11.23"><CODE>.ELSE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Reverse the current condition.</P>
|
|
|
|
|
|
<H2><A NAME=".ELSEIF"></A> <A NAME="ss11.24">11.24</A> <A HREF="#toc11.24"><CODE>.ELSEIF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Reverse current condition and test a new one.</P>
|
|
|
|
|
|
<H2><A NAME=".END"></A> <A NAME="ss11.25">11.25</A> <A HREF="#toc11.25"><CODE>.END</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Forced end of assembly. Assembly stops at this point, even if the command
|
|
is read from an include file.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDENUM"></A> <A NAME="ss11.26">11.26</A> <A HREF="#toc11.26"><CODE>.ENDENUM</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>End a <CODE>
|
|
<A HREF="#.ENUM">.ENUM</A></CODE> declaration.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDIF"></A> <A NAME="ss11.27">11.27</A> <A HREF="#toc11.27"><CODE>.ENDIF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Close a <CODE>
|
|
<A HREF="#.IF">.IF...</A></CODE> or
|
|
<CODE>
|
|
<A HREF="#.ELSE">.ELSE</A></CODE> branch.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDMACRO"></A> <A NAME="ss11.28">11.28</A> <A HREF="#toc11.28"><CODE>.ENDMAC, .ENDMACRO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Marks the end of a macro definition. Note, <CODE>.ENDMACRO</CODE> should be on
|
|
its own line to successfully end the macro definition. It is possible to use
|
|
<CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> to create a symbol that references
|
|
<CODE>.ENDMACRO</CODE> without ending the macro definition.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro new_mac
|
|
.define startmac .macro
|
|
.define endmac .endmacro
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.DELMACRO">.DELMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.EXITMACRO">.EXITMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.MACRO">.MACRO</A></CODE></P>
|
|
<P>See also section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDPROC"></A> <A NAME="ss11.29">11.29</A> <A HREF="#toc11.29"><CODE>.ENDPROC</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>End of the local lexical level (see <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE>).</P>
|
|
|
|
|
|
<H2><A NAME=".ENDREPEAT"></A> <A NAME="ss11.30">11.30</A> <A HREF="#toc11.30"><CODE>.ENDREP, .ENDREPEAT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>End a <CODE>
|
|
<A HREF="#.REPEAT">.REPEAT</A></CODE> block.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDSCOPE"></A> <A NAME="ss11.31">11.31</A> <A HREF="#toc11.31"><CODE>.ENDSCOPE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>End of the local lexical level (see <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE>).</P>
|
|
|
|
|
|
<H2><A NAME=".ENDSTRUCT"></A> <A NAME="ss11.32">11.32</A> <A HREF="#toc11.32"><CODE>.ENDSTRUCT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Ends a struct definition. See the <CODE>
|
|
<A HREF="#.STRUCT">.STRUCT</A></CODE>
|
|
command and the separate section named
|
|
<A HREF="#structs">"Structs and unions"</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".ENDUNION"></A> <A NAME="ss11.33">11.33</A> <A HREF="#toc11.33"><CODE>.ENDUNION</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Ends a union definition. See the <CODE>
|
|
<A HREF="#.UNION">.UNION</A></CODE>
|
|
command and the separate section named
|
|
<A HREF="#structs">"Structs and unions"</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".ENUM"></A> <A NAME="ss11.34">11.34</A> <A HREF="#toc11.34"><CODE>.ENUM</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Start an enumeration. This directive is very similar to the C <CODE>enum</CODE>
|
|
keyword. If a name is given, a new scope is created for the enumeration,
|
|
otherwise the enumeration members are placed in the enclosing scope.</P>
|
|
<P>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 preceding, plus
|
|
one. That behaviour may be overridden by an explicit assignment. Two symbols
|
|
may have the same value.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.enum errorcodes
|
|
no_error
|
|
file_error
|
|
parse_error
|
|
.endenum
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The above example will create a new scope named <CODE>errorcodes</CODE> with three
|
|
symbols in it that get the values 0, 1, and 2 respectively. Another way
|
|
to write that would have been:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope errorcodes
|
|
no_error = 0
|
|
file_error = 1
|
|
parse_error = 2
|
|
.endscope
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Please note that explicit scoping must be used to access the identifiers:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.word errorcodes::no_error
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>A more complex example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.enum
|
|
EUNKNOWN = -1
|
|
EOK
|
|
EFILE
|
|
EBUSY
|
|
EAGAIN
|
|
EWOULDBLOCK = EAGAIN
|
|
.endenum
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In that 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 that scope
|
|
without explicit scoping. The first member (<CODE>EUNKNOWN</CODE>) has the value -1.
|
|
The values for the following members are incremented by one; so, <CODE>EOK</CODE>
|
|
would be zero, and so on. <CODE>EWOULDBLOCK</CODE> is an alias for <CODE>EAGAIN</CODE>; so,
|
|
it has an override for the value, using an already defined symbol.</P>
|
|
|
|
|
|
<H2><A NAME=".ERROR"></A> <A NAME="ss11.35">11.35</A> <A HREF="#toc11.35"><CODE>.ERROR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Force an assembly error. The assembler will output an error message
|
|
preceded by "User error". Assembly is continued but no object file will
|
|
generated.</P>
|
|
<P>This command may be used to check for initial conditions that must be
|
|
set before assembling a source file.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if foo = 1
|
|
...
|
|
.elseif bar = 1
|
|
...
|
|
.else
|
|
.error "Must define foo or bar!"
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.FATAL">.FATAL</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.OUT">.OUT</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.WARNING">.WARNING</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".EXITMACRO"></A> <A NAME="ss11.36">11.36</A> <A HREF="#toc11.36"><CODE>.EXITMAC, .EXITMACRO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Abort a macro expansion immediately. This command is often useful in
|
|
recursive macros.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.DELMACRO">.DELMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.ENDMACRO">.ENDMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.MACRO">.MACRO</A></CODE></P>
|
|
<P>See also section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".EXPORT"></A> <A NAME="ss11.37">11.37</A> <A HREF="#toc11.37"><CODE>.EXPORT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Make symbols accessible from other modules. Must be followed by a comma
|
|
separated list of symbols to export, with each one optionally followed by an
|
|
address specification and (also optional) an assignment. Using an additional
|
|
assignment in the export statement allows to define and export a symbol in
|
|
one statement. The default is to export the symbol with the address size it
|
|
actually has. The assembler will issue a warning, if the symbol is exported
|
|
with an address size smaller than the actual address size.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.export foo
|
|
.export bar: far
|
|
.export foobar: far = foo * bar
|
|
.export baz := foobar, zap: far = baz - bar
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>As with constant definitions, using <CODE>:=</CODE> instead of <CODE>=</CODE> marks the
|
|
symbols as a label.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.EXPORTZP">.EXPORTZP</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".EXPORTZP"></A> <A NAME="ss11.38">11.38</A> <A HREF="#toc11.38"><CODE>.EXPORTZP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Make symbols accessible from other modules. Must be followed by a comma
|
|
separated list of symbols to export. The exported symbols are explicitly
|
|
marked as zero page symbols. An assignment may be included in the
|
|
<CODE>.EXPORTZP</CODE> statement. This allows to define and export a symbol in one
|
|
statement.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.exportzp foo, bar
|
|
.exportzp baz := $02
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.EXPORT">.EXPORT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".FARADDR"></A> <A NAME="ss11.39">11.39</A> <A HREF="#toc11.39"><CODE>.FARADDR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define far (24 bit) address data. The command must be followed by a
|
|
sequence of (not necessarily constant) expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.faraddr DrawCircle, DrawRectangle, DrawHexagon
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ADDR">.ADDR</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".FATAL"></A> <A NAME="ss11.40">11.40</A> <A HREF="#toc11.40"><CODE>.FATAL</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Force an assembly error and terminate assembly. The assembler will output an
|
|
error message preceded by "User error" and will terminate assembly
|
|
immediately.</P>
|
|
<P>This command may be used to check for initial conditions that must be
|
|
set before assembling a source file.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if foo = 1
|
|
...
|
|
.elseif bar = 1
|
|
...
|
|
.else
|
|
.fatal "Must define foo or bar!"
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ERROR">.ERROR</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.OUT">.OUT</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.WARNING">.WARNING</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".FEATURE"></A> <A NAME="ss11.41">11.41</A> <A HREF="#toc11.41"><CODE>.FEATURE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This directive may be used to enable one or more compatibility features
|
|
of the assembler. While the use of <CODE>.FEATURE</CODE> should be avoided when
|
|
possible, it may be useful when porting sources written for other
|
|
assemblers. After the feature name an optional '+' or '-' may specify whether
|
|
to enable or disable the feature (enable if omitted). Multiple features may be
|
|
enabled, separated by commas. Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; enable c_comments
|
|
.feature c_comments
|
|
.feature c_comments +
|
|
; enable force_range, disable underline_in_numbers, enable labels_without_colons
|
|
.feature force_range, underline_in_numbers -, labels_without_colons +
|
|
.feature force_range +, underline_in_numbers off, labels_without_colons on
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The following features are available:</P>
|
|
<P>
|
|
<DL>
|
|
|
|
<DT><B><CODE>at_in_identifiers</CODE>
|
|
<A NAME="at_in_identifiers"></A> </B><DD>
|
|
<P>Accept the at character ('@') as a valid character in identifiers. The
|
|
at character is not allowed to start an identifier, even with this
|
|
feature enabled.</P>
|
|
|
|
<DT><B><CODE>bracket_as_indirect</CODE>
|
|
<A NAME="bracket_as_indirect"></A> </B><DD>
|
|
<P>Use <CODE>[]</CODE> instead of <CODE>()</CODE> for the indirect addressing modes.
|
|
Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda [$82]
|
|
lda [$82,x]
|
|
lda [$82],y
|
|
jmp [$fffe]
|
|
jmp [table,x]
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
<EM>Note:</EM> This should not be used in 65186 mode because it conflicts with
|
|
the 65816 instruction syntax for far addressing. See the section covering
|
|
<CODE>
|
|
<A HREF="#address-sizes">address sizes</A></CODE> for more information.</P>
|
|
|
|
<DT><B><CODE>c_comments</CODE>
|
|
<A NAME="c_comments"></A> </B><DD>
|
|
<P>Allow C like comments using <CODE>/*</CODE> and <CODE>*/</CODE> as left and right
|
|
comment terminators. Note that C comments may not be nested. There's also a
|
|
pitfall when using C like comments: All statements must be terminated by
|
|
"end-of-line". Using C like comments, it is possible to hide the newline,
|
|
which results in error messages. See the following non working example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda #$00 /* This comment hides the newline
|
|
*/ sta $82
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
<DT><B><CODE>dollar_in_identifiers</CODE>
|
|
<A NAME="dollar_in_identifiers"></A> </B><DD>
|
|
<P>Accept the dollar sign ('$') as a valid character in identifiers. The
|
|
dollar character is not allowed to start an identifier, even with this
|
|
feature enabled.</P>
|
|
|
|
<DT><B><CODE>dollar_is_pc</CODE>
|
|
<A NAME="dollar_is_pc"></A> </B><DD>
|
|
<P>The dollar sign may be used as an alias for the star ('*'), which
|
|
gives the value of the current PC in expressions.
|
|
Note: Assignment to the pseudo variable is not allowed.</P>
|
|
|
|
<DT><B><CODE>force_range</CODE>
|
|
<A NAME="force_range"></A> </B><DD>
|
|
<P>Force expressions into their valid range for immediate addressing and
|
|
storage operators like <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.WORD">.WORD</A></CODE>. Be very careful with this one,
|
|
since it will completely disable error checks.</P>
|
|
|
|
<DT><B><CODE>labels_without_colons</CODE>
|
|
<A NAME="labels_without_colons"></A> </B><DD>
|
|
<P>Allow labels without a trailing colon. These labels are only accepted,
|
|
if they start at the beginning of a line (no leading white space).</P>
|
|
|
|
<DT><B><CODE>leading_dot_in_identifiers</CODE>
|
|
<A NAME="leading_dot_in_identifiers"></A> </B><DD>
|
|
<P>Accept the dot ('.') as the first character of an identifier. This may be
|
|
used for example to create macro names that start with a dot emulating
|
|
control directives of other assemblers. Note however, that none of the
|
|
reserved keywords built into the assembler, that starts with a dot, may be
|
|
overridden. When using this feature, you may also get into trouble if
|
|
later versions of the assembler define new keywords starting with a dot.</P>
|
|
|
|
<DT><B><CODE>line_continuations</CODE>
|
|
<A NAME="line_continuations"></A> </B><DD>
|
|
<P>Switch on or off line continuations using the backslash character
|
|
before a newline. The option is off by default.
|
|
Note: Line continuations do not work in a comment. A backslash at the
|
|
end of a comment is treated as part of the comment and does not trigger
|
|
line continuation.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.feature line_continuations + ; Allow line continuations
|
|
|
|
lda \
|
|
#$20 ; This is legal now
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>For backward compatibility reasons, the <CODE>.LINECONT +</CODE> control command
|
|
is also supported and enables the same feature.</P>
|
|
|
|
<DT><B><CODE>long_jsr_jmp_rts</CODE>
|
|
<A NAME="long_jsr_jmp_rts"></A> </B><DD>
|
|
<P>Affects 65816 mode only.</P>
|
|
<P>Allows <CODE>jsr</CODE> and <CODE>jmp</CODE> to produce long jumps if the target
|
|
address has been previously declared in a <CODE>far</CODE> segment,
|
|
or imported as <CODE>far</CODE>.
|
|
Otherwise <CODE>jsl</CODE> and <CODE>jml</CODE> must be used instead.</P>
|
|
<P>Also allows <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE> to convert <CODE>rts</CODE>
|
|
to a long return <CODE>rtl</CODE> when the enclosing scope or memory model
|
|
indicates returning from a <CODE>far</CODE> procedure.</P>
|
|
<P>This permits compatibility with the old behavior of this assembler, or other
|
|
assemblers which similarly allowed <CODE>jsr</CODE> and <CODE>jmp</CODE> to be used
|
|
this way.</P>
|
|
|
|
<DT><B><CODE>loose_char_term</CODE>
|
|
<A NAME="loose_char_term"></A> </B><DD>
|
|
<P>Accept single quotes as well as double quotes as terminators for char
|
|
constants.</P>
|
|
|
|
<DT><B><CODE>loose_string_term</CODE>
|
|
<A NAME="loose_string_term"></A> </B><DD>
|
|
<P>Accept single quotes as well as double quotes as terminators for string
|
|
constants.</P>
|
|
|
|
<DT><B><CODE>missing_char_term</CODE>
|
|
<A NAME="missing_char_term"></A> </B><DD>
|
|
<P>Accept single quoted character constants where the terminating quote is
|
|
missing.
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda #'a
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
<EM>Note:</EM> This does not work in conjunction with <CODE>.FEATURE
|
|
loose_string_term</CODE>, since in this case the input would be ambiguous.</P>
|
|
|
|
<DT><B><CODE>org_per_seg</CODE>
|
|
<A NAME="org_per_seg"></A> </B><DD>
|
|
<P>This feature makes relocatable/absolute mode local to the current segment.
|
|
Using <CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> when <CODE>org_per_seg</CODE> is in
|
|
effect will only enable absolute mode for the current segment. Dito for
|
|
<CODE>
|
|
<A HREF="#.RELOC">.RELOC</A></CODE>.</P>
|
|
|
|
<DT><B><CODE>pc_assignment</CODE>
|
|
<A NAME="pc_assignment"></A> </B><DD>
|
|
<P>Allow assignments to the PC symbol ('*' or '$' if <CODE>dollar_is_pc</CODE>
|
|
is enabled). Such an assignment is handled identical to the <CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> command (which is usually not needed, so just
|
|
removing the lines with the assignments may also be an option when porting
|
|
code written for older assemblers).</P>
|
|
|
|
<DT><B><CODE>string_escapes</CODE>
|
|
<A NAME="string_escapes"></A> </B><DD>
|
|
<P>Allow C-style backslash escapes within string constants to embed
|
|
special characters. The following escapes are accepted:
|
|
<UL>
|
|
<LI><CODE>\\</CODE> backslash (<CODE>$5C</CODE>)</LI>
|
|
<LI><CODE>\'</CODE> single quote (<CODE>$27</CODE>)</LI>
|
|
<LI><CODE>\"</CODE> double quote (<CODE>$22</CODE>)</LI>
|
|
<LI><CODE>\t</CODE> tab (<CODE>$09</CODE>)</LI>
|
|
<LI><CODE>\r</CODE> carriage return (<CODE>$0D</CODE>)</LI>
|
|
<LI><CODE>\n</CODE> newline (<CODE>$0A</CODE>)</LI>
|
|
<LI><CODE>\xNN</CODE> (<CODE>$NN</CODE>)</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Note that string escapes are converted to platform-specific characters in
|
|
the same way that other characters are converted.</P>
|
|
|
|
<DT><B><CODE>ubiquitous_idents</CODE>
|
|
<A NAME="ubiquitous_idents"></A> </B><DD>
|
|
<P>Allow the use of instructions names as names for macros and symbols. This
|
|
makes it possible to "overload" instructions by defining a macro with the
|
|
same name. This does also make it possible to introduce hard to find errors
|
|
in your code, so be careful!</P>
|
|
|
|
<DT><B><CODE>underline_in_numbers</CODE>
|
|
<A NAME="underline_in_numbers"></A> </B><DD>
|
|
<P>Allow underlines within numeric constants. These may be used for grouping
|
|
the digits of numbers for easier reading.
|
|
Example:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.feature underline_in_numbers
|
|
.word %1100001110100101
|
|
.word %1100_0011_1010_0101 ; Identical but easier to read
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
</DL>
|
|
</P>
|
|
<P>It is also possible to specify features on the command line using the
|
|
<CODE>
|
|
<A HREF="#option--feature">--feature</A></CODE> command line option.
|
|
This is useful when translating sources written for older assemblers, when
|
|
you don't want to change the source code.</P>
|
|
<P>As an example, to translate sources written for Andre Fachats xa65
|
|
assembler, the features</P>
|
|
<P>
|
|
<PRE>
|
|
labels_without_colons, pc_assignment, loose_char_term
|
|
|
|
</PRE>
|
|
</P>
|
|
<P>may be helpful. They do not make ca65 completely compatible, so you may not
|
|
be able to translate the sources without changes, even when enabling these
|
|
features. However, I have found several sources that translate without
|
|
problems when enabling these features on the command line.</P>
|
|
|
|
|
|
<H2><A NAME=".FOPT"></A> <A NAME="ss11.42">11.42</A> <A HREF="#toc11.42"><CODE>.FILEOPT, .FOPT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Insert an option string into the object file. There are two forms of
|
|
this command, one specifies the option by a keyword, the second
|
|
specifies it as a number. Since usage of the second one needs knowledge
|
|
of the internal encoding, its use is not recommended and I will only
|
|
describe the first form here.</P>
|
|
<P>The command is followed by one of the keywords</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
author
|
|
comment
|
|
compiler
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>a comma and a string. The option is written into the object file
|
|
together with the string value. This is currently unidirectional and
|
|
there is no way to actually use these options once they are in the
|
|
object file.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.fileopt comment, "Code stolen from my brother"
|
|
.fileopt compiler, "BASIC 2.0"
|
|
.fopt author, "J. R. User"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".FORCEIMPORT"></A> <A NAME="ss11.43">11.43</A> <A HREF="#toc11.43"><CODE>.FORCEIMPORT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Import an absolute symbol from another module. The command is followed by a
|
|
comma separated list of symbols to import. The command is similar to <CODE>
|
|
<A HREF="#.IMPORT">.IMPORT</A></CODE>, but the import reference is always
|
|
written to the generated object file, even if the symbol is never referenced
|
|
(<CODE>
|
|
<A HREF="#.IMPORT">.IMPORT</A></CODE> will not generate import
|
|
references for unused symbols).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.forceimport needthisone, needthistoo
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.IMPORT">.IMPORT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".GLOBAL"></A> <A NAME="ss11.44">11.44</A> <A HREF="#toc11.44"><CODE>.GLOBAL</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Declare symbols as global. Must be followed by a comma separated list of
|
|
symbols to declare. Symbols from the list, that are defined somewhere in the
|
|
source, are exported, all others are imported. Additional <CODE>
|
|
<A HREF="#.IMPORT">.IMPORT</A></CODE> or <CODE>
|
|
<A HREF="#.EXPORT">.EXPORT</A></CODE> commands for the same symbol are allowed.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.global foo, bar
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".GLOBALZP"></A> <A NAME="ss11.45">11.45</A> <A HREF="#toc11.45"><CODE>.GLOBALZP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Declare symbols as global. Must be followed by a comma separated list of
|
|
symbols to declare. Symbols from the list, that are defined somewhere in the
|
|
source, are exported, all others are imported. Additional <CODE>
|
|
<A HREF="#.IMPORTZP">.IMPORTZP</A></CODE> or <CODE>
|
|
<A HREF="#.EXPORTZP">.EXPORTZP</A></CODE> commands for the same symbol are allowed. The symbols
|
|
in the list are explicitly marked as zero page symbols.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.globalzp foo, bar
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
<H2><A NAME=".HIBYTES"></A> <A NAME="ss11.46">11.46</A> <A HREF="#toc11.46"><CODE>.HIBYTES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define byte sized data by extracting only the high byte (that is, bits 8-15) from
|
|
each expression. This is equivalent to <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE> with
|
|
the operator '>' prepended to each expression in its list.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.lobytes $1234, $2345, $3456, $4567
|
|
.hibytes $fedc, $edcb, $dcba, $cba9
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>which is equivalent to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.byte $34, $45, $56, $67
|
|
.byte $fe, $ed, $dc, $cb
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define MyTable TableItem0, TableItem1, TableItem2, TableItem3
|
|
|
|
TableLookupLo: .lobytes MyTable
|
|
TableLookupHi: .hibytes MyTable
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>which is equivalent to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3
|
|
TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.LOBYTES">.LOBYTES</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.BANKBYTES">.BANKBYTES</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".I16"></A> <A NAME="ss11.47">11.47</A> <A HREF="#toc11.47"><CODE>.I16</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Valid only in 65816 mode. Assume the index registers are 16 bit.</P>
|
|
<P>Note: This command will not emit any code, it will tell the assembler to
|
|
create 16 bit operands for immediate operands.</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.I8">.I8</A></CODE> and <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE> commands.</P>
|
|
|
|
|
|
<H2><A NAME=".I8"></A> <A NAME="ss11.48">11.48</A> <A HREF="#toc11.48"><CODE>.I8</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Valid only in 65816 mode. Assume the index registers are 8 bit.</P>
|
|
<P>Note: This command will not emit any code, it will tell the assembler to
|
|
create 8 bit operands for immediate operands.</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.I16">.I16</A></CODE> and <CODE>
|
|
<A HREF="#.SMART">.SMART</A></CODE> commands.</P>
|
|
|
|
|
|
<H2><A NAME=".IF"></A> <A NAME="ss11.49">11.49</A> <A HREF="#toc11.49"><CODE>.IF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Evaluate an expression and switch assembler output
|
|
on or off depending on the expression. The expression must be a constant
|
|
expression, that is, all operands must be defined.</P>
|
|
<P>A expression value of zero evaluates to FALSE, any other value evaluates
|
|
to TRUE.</P>
|
|
|
|
|
|
<H2><A NAME=".IFBLANK"></A> <A NAME="ss11.50">11.50</A> <A HREF="#toc11.50"><CODE>.IFBLANK</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if there are any remaining tokens in this line,
|
|
and evaluate to FALSE if this is the case, and to TRUE otherwise. If the
|
|
condition is not true, further lines are not assembled until an <CODE>
|
|
<A HREF="#.ELSE">.ELSE</A></CODE>, <CODE>
|
|
<A HREF="#.ELSEIF">.ELSEIF</A></CODE> or
|
|
<CODE>
|
|
<A HREF="#.ENDIF">.ENDIF</A></CODE> directive.</P>
|
|
<P>This command is often used to check if a macro parameter was given. Since an
|
|
empty macro parameter will evaluate to nothing, the condition will evaluate
|
|
to TRUE if an empty parameter was given.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro arg1, arg2
|
|
.ifblank arg2
|
|
lda #arg1
|
|
.else
|
|
lda #arg2
|
|
.endif
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.BLANK">.BLANK</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFCONST"></A> <A NAME="ss11.51">11.51</A> <A HREF="#toc11.51"><CODE>.IFCONST</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Evaluate an expression and switch assembler output
|
|
on or off depending on the constness of the expression.</P>
|
|
<P>A const expression evaluates to to TRUE, a non const expression (one
|
|
containing an imported or currently undefined symbol) evaluates to
|
|
FALSE.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.CONST">.CONST</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFDEF"></A> <A NAME="ss11.52">11.52</A> <A HREF="#toc11.52"><CODE>.IFDEF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if a symbol is defined. Must be followed by
|
|
a symbol name. The condition is true if the given symbol is already
|
|
defined, and false otherwise.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.DEFINED">.DEFINED</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFNBLANK"></A> <A NAME="ss11.53">11.53</A> <A HREF="#toc11.53"><CODE>.IFNBLANK</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if there are any remaining tokens in this line,
|
|
and evaluate to TRUE if this is the case, and to FALSE otherwise. If the
|
|
condition is not true, further lines are not assembled until an <CODE>
|
|
<A HREF="#.ELSE">.ELSE</A></CODE>, <CODE>
|
|
<A HREF="#.ELSEIF">.ELSEIF</A></CODE> or
|
|
<CODE>
|
|
<A HREF="#.ENDIF">.ENDIF</A></CODE> directive.</P>
|
|
<P>This command is often used to check if a macro parameter was given.
|
|
Since an empty macro parameter will evaluate to nothing, the condition
|
|
will evaluate to FALSE if an empty parameter was given.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro arg1, arg2
|
|
lda #arg1
|
|
.ifnblank arg2
|
|
lda #arg2
|
|
.endif
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.BLANK">.BLANK</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFNDEF"></A> <A NAME="ss11.54">11.54</A> <A HREF="#toc11.54"><CODE>.IFNDEF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if a symbol is defined. Must be followed by
|
|
a symbol name. The condition is true if the given symbol is not
|
|
defined, and false otherwise.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.DEFINED">.DEFINED</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFNREF"></A> <A NAME="ss11.55">11.55</A> <A HREF="#toc11.55"><CODE>.IFNREF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if a symbol is referenced. Must be followed
|
|
by a symbol name. The condition is true if the given symbol was
|
|
not referenced before, and false otherwise.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.REFERENCED">.REFERENCED</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IFP02"></A> <A NAME="ss11.56">11.56</A> <A HREF="#toc11.56"><CODE>.IFP02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 6502 mode
|
|
(see <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFP4510"></A> <A NAME="ss11.57">11.57</A> <A HREF="#toc11.57"><CODE>.IFP4510</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 4510 mode
|
|
(see <CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFP816"></A> <A NAME="ss11.58">11.58</A> <A HREF="#toc11.58"><CODE>.IFP816</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 65816 mode
|
|
(see <CODE>
|
|
<A HREF="#.P816">.P816</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFPC02"></A> <A NAME="ss11.59">11.59</A> <A HREF="#toc11.59"><CODE>.IFPC02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 65C02 mode
|
|
(see <CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFPDTV"></A> <A NAME="ss11.60">11.60</A> <A HREF="#toc11.60"><CODE>.IFPDTV</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 6502DTV mode
|
|
(see <CODE>
|
|
<A HREF="#.PDTV">.PDTV</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFPSC02"></A> <A NAME="ss11.61">11.61</A> <A HREF="#toc11.61"><CODE>.IFPSC02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if the assembler is currently in 65SC02 mode
|
|
(see <CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE> command).</P>
|
|
|
|
|
|
<H2><A NAME=".IFREF"></A> <A NAME="ss11.62">11.62</A> <A HREF="#toc11.62"><CODE>.IFREF</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Conditional assembly: Check if a symbol is referenced. Must be followed
|
|
by a symbol name. The condition is true if the given symbol was
|
|
referenced before, and false otherwise.</P>
|
|
<P>This command may be used to build subroutine libraries in include files
|
|
(you may use separate object modules for this purpose too).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.ifref ToHex ; If someone used this subroutine
|
|
ToHex: tay ; Define subroutine
|
|
lda HexTab,y
|
|
rts
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.REFERENCED">.REFERENCED</A></CODE>, and
|
|
<CODE>
|
|
<A HREF="#.REFERTO">.REFERTO</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IMPORT"></A> <A NAME="ss11.63">11.63</A> <A HREF="#toc11.63"><CODE>.IMPORT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Import a symbol from another module. The command is followed by a comma
|
|
separated list of symbols to import, with each one optionally followed by
|
|
an address specification.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.import foo
|
|
.import bar: zeropage
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.IMPORTZP">.IMPORTZP</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".IMPORTZP"></A> <A NAME="ss11.64">11.64</A> <A HREF="#toc11.64"><CODE>.IMPORTZP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Import a symbol from another module. The command is followed by a comma
|
|
separated list of symbols to import. The symbols are explicitly imported
|
|
as zero page symbols (that is, symbols with values in byte range).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.importzp foo, bar
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.IMPORT">.IMPORT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".INCBIN"></A> <A NAME="ss11.65">11.65</A> <A HREF="#toc11.65"><CODE>.INCBIN</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Include a file as binary data. The command expects a string argument
|
|
that is the name of a file to include literally in the current segment.
|
|
In addition to that, a start offset and a size value may be specified,
|
|
separated by commas. If no size is specified, all of the file from the
|
|
start offset to end-of-file is used. If no start position is specified
|
|
either, zero is assumed (which means that the whole file is inserted).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Include whole file
|
|
.incbin "sprites.dat"
|
|
|
|
; Include file starting at offset 256
|
|
.incbin "music.dat", $100
|
|
|
|
; Read 100 bytes starting at offset 200
|
|
.incbin "graphics.dat", 200, 100
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".INCLUDE"></A> <A NAME="ss11.66">11.66</A> <A HREF="#toc11.66"><CODE>.INCLUDE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Include another file. Include files may be nested up to a depth of 16.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.include "subs.inc"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".INTERRUPTOR"></A> <A NAME="ss11.67">11.67</A> <A HREF="#toc11.67"><CODE>.INTERRUPTOR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Export a symbol and mark it as an interruptor. This may be used together
|
|
with the linker to build a table of interruptor subroutines that are called
|
|
in an interrupt.</P>
|
|
<P>Note: The linker has a feature to build a table of marked routines, but it
|
|
is your code that must call these routines, so just declaring a symbol as
|
|
interruptor does nothing by itself.</P>
|
|
<P>An interruptor is always exported as an absolute (16 bit) symbol. You don't
|
|
need to use an additional <CODE>.export</CODE> statement, this is implied by
|
|
<CODE>.interruptor</CODE>. It may have an optional priority that is separated by a
|
|
comma. Higher numeric values mean a higher priority. If no priority is
|
|
given, the default priority of 7 is used. Be careful when assigning
|
|
priorities to your own module constructors so they won't interfere with the
|
|
ones in the cc65 library.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.interruptor IrqHandler
|
|
.interruptor Handler, 16
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See the <CODE>
|
|
<A HREF="#.CONDES">.CONDES</A></CODE> command and the separate
|
|
section
|
|
<A HREF="#condes">Module constructors/destructors</A> explaining
|
|
the feature in more detail.</P>
|
|
|
|
|
|
<H2><A NAME=".LIST"></A> <A NAME="ss11.68">11.68</A> <A HREF="#toc11.68"><CODE>.LIST</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable output to the listing. The command can be followed by a boolean
|
|
switch ("on", "off", "+" or "-") and will enable or disable listing
|
|
output.
|
|
The option has no effect if the listing is not enabled by the command line
|
|
switch -l. If -l is used, an internal counter is set to 1. Lines are output
|
|
to the listing file, if the counter is greater than zero, and suppressed if
|
|
the counter is zero. Each use of <CODE>.LIST</CODE> will increment or decrement the
|
|
counter.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.list on ; Enable listing output
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".LISTBYTES"></A> <A NAME="ss11.69">11.69</A> <A HREF="#toc11.69"><CODE>.LISTBYTES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Set, how many bytes are shown in the listing for one source line. The
|
|
default is 12, so the listing will show only the first 12 bytes for any
|
|
source line that generates more than 12 bytes of code or data.
|
|
The directive needs an argument, which is either "unlimited", or an
|
|
integer constant in the range 4..255.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.listbytes unlimited ; List all bytes
|
|
.listbytes 12 ; List the first 12 bytes
|
|
.incbin "data.bin" ; Include large binary file
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".LITERAL"></A> <A NAME="ss11.70">11.70</A> <A HREF="#toc11.70"><CODE>.LITERAL</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define byte sized data. Must be followed by a sequence of (byte ranged)
|
|
expressions or strings. Strings will disregard the current character
|
|
mapping definition and will be interpreted literally.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.literal "Hello "
|
|
.literal "world", $0D, $00
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ASCIIZ">.ASCIIZ</A></CODE>,<CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".LOBYTES"></A> <A NAME="ss11.71">11.71</A> <A HREF="#toc11.71"><CODE>.LOBYTES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define byte sized data by extracting only the low byte (that is, bits 0-7) from
|
|
each expression. This is equivalent to <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE> with
|
|
the operator '<' prepended to each expression in its list.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.lobytes $1234, $2345, $3456, $4567
|
|
.hibytes $fedc, $edcb, $dcba, $cba9
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>which is equivalent to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.byte $34, $45, $56, $67
|
|
.byte $fe, $ed, $dc, $cb
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define MyTable TableItem0, TableItem1, TableItem2, TableItem3
|
|
|
|
TableLookupLo: .lobytes MyTable
|
|
TableLookupHi: .hibytes MyTable
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>which is equivalent to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
TableLookupLo: .byte <TableItem0, <TableItem1, <TableItem2, <TableItem3
|
|
TableLookupHi: .byte >TableItem0, >TableItem1, >TableItem2, >TableItem3
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.HIBYTES">.HIBYTES</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.BANKBYTES">.BANKBYTES</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".LOCAL"></A> <A NAME="ss11.72">11.72</A> <A HREF="#toc11.72"><CODE>.LOCAL</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This command may only be used inside a macro definition. It declares a
|
|
list of identifiers as local to the macro expansion.</P>
|
|
<P>A problem when using macros are labels: Since they don't change their name,
|
|
you get a "duplicate symbol" error if the macro is expanded the second time.
|
|
Labels declared with <CODE>
|
|
<A HREF="#.LOCAL">.LOCAL</A></CODE> have their
|
|
name mapped to an internal unique name (<CODE>___ABCD__</CODE>) with each macro
|
|
invocation.</P>
|
|
<P>Some other assemblers start a new lexical block inside a macro expansion.
|
|
This has some drawbacks however, since that will not allow <EM>any</EM> symbol
|
|
to be visible outside a macro, a feature that is sometimes useful. The
|
|
<CODE>
|
|
<A HREF="#.LOCAL">.LOCAL</A></CODE> command is in my eyes a better way
|
|
to address the problem.</P>
|
|
<P>You get an error when using <CODE>
|
|
<A HREF="#.LOCAL">.LOCAL</A></CODE> outside
|
|
a macro.</P>
|
|
|
|
|
|
<H2><A NAME=".LOCALCHAR"></A> <A NAME="ss11.73">11.73</A> <A HREF="#toc11.73"><CODE>.LOCALCHAR</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Defines the character that start "cheap" local labels. You may use one
|
|
of '@' and '?' as start character. The default is '@'.</P>
|
|
<P>Cheap local labels are labels that are visible only between two non
|
|
cheap labels. This way you can reuse identifiers like "<CODE>loop</CODE>" without
|
|
using explicit lexical nesting.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.localchar '?'
|
|
|
|
Clear: lda #$00 ; Global label
|
|
?Loop: sta Mem,y ; Local label
|
|
dey
|
|
bne ?Loop ; Ok
|
|
rts
|
|
Sub: ... ; New global label
|
|
bne ?Loop ; ERROR: Unknown identifier!
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".MACPACK"></A> <A NAME="ss11.74">11.74</A> <A HREF="#toc11.74"><CODE>.MACPACK</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Insert a predefined macro package. The command is followed by an
|
|
identifier specifying the macro package to insert. Available macro
|
|
packages are:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
atari Defines the scrcode macro.
|
|
cbm Defines the scrcode macro.
|
|
cpu Defines constants for the .CPU variable.
|
|
generic Defines generic macros like add, sub, and blt.
|
|
longbranch Defines conditional long-jump macros.
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Including a macro package twice, or including a macro package that
|
|
redefines already existing macros will lead to an error.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macpack longbranch ; Include macro package
|
|
|
|
cmp #$20 ; Set condition codes
|
|
jne Label ; Jump long on condition
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Macro packages are explained in more detail in section
|
|
<A HREF="#macropackages">Macro packages</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".MACRO"></A> <A NAME="ss11.75">11.75</A> <A HREF="#toc11.75"><CODE>.MAC, .MACRO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Start a classic macro definition. The command is followed by an identifier
|
|
(the macro name) and optionally by a comma separated list of identifiers
|
|
that are macro parameters. A macro definition is terminated by <CODE>
|
|
<A HREF="#.ENDMACRO">.ENDMACRO</A></CODE>.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro ldax arg ; Define macro ldax
|
|
lda arg
|
|
ldx arg+1
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.DELMACRO">.DELMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.ENDMACRO">.ENDMACRO</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.EXITMACRO">.EXITMACRO</A></CODE></P>
|
|
<P>See also section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".ORG"></A> <A NAME="ss11.76">11.76</A> <A HREF="#toc11.76"><CODE>.ORG</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Start a section of absolute code. The command is followed by a constant
|
|
expression that gives the new PC counter location for which the code is
|
|
assembled. Use <CODE>
|
|
<A HREF="#.RELOC">.RELOC</A></CODE> to switch back to
|
|
relocatable code.</P>
|
|
<P>By default, absolute/relocatable mode is global (valid even when switching
|
|
segments). Using <CODE>.FEATURE
|
|
<A HREF="#org_per_seg">org_per_seg</A></CODE>
|
|
it can be made segment local.</P>
|
|
<P>Please note that you <EM>do not need</EM> <CODE>.ORG</CODE> in most cases. Placing
|
|
code at a specific address is the job of the linker, not the assembler, so
|
|
there is usually no reason to assemble code to a specific address.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.org $7FF ; Emit code starting at $7FF
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".OUT"></A> <A NAME="ss11.77">11.77</A> <A HREF="#toc11.77"><CODE>.OUT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Output a string to the console without producing an error. This command
|
|
is similar to <CODE>.ERROR</CODE>, however, it does not force an assembler error
|
|
that prevents the creation of an object file.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.out "This code was written by the codebuster(tm)"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ERROR">.ERROR</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.FATAL">.FATAL</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.WARNING">.WARNING</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".P02"></A> <A NAME="ss11.78">11.78</A> <A HREF="#toc11.78"><CODE>.P02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 6502 instruction set, disable 65SC02, 65C02 and 65816
|
|
instructions. This is the default if not overridden by the
|
|
<CODE>
|
|
<A HREF="#option--cpu">--cpu</A></CODE> command line option.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE>, <CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE>, <CODE>
|
|
<A HREF="#.P816">.P816</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".P4510"></A> <A NAME="ss11.79">11.79</A> <A HREF="#toc11.79"><CODE>.P4510</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 4510 instruction set. This is a superset of the 65C02 and
|
|
6502 instruction sets.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE>, <CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE>, <CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.P816">.P816</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".P816"></A> <A NAME="ss11.80">11.80</A> <A HREF="#toc11.80"><CODE>.P816</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 65816 instruction set. This is a superset of the 65SC02 and
|
|
6502 instruction sets.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE>, <CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE>, <CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PAGELENGTH"></A> <A NAME="ss11.81">11.81</A> <A HREF="#toc11.81"><CODE>.PAGELEN, .PAGELENGTH</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Set the page length for the listing. Must be followed by an integer
|
|
constant. The value may be "unlimited", or in the range 32 to 127. The
|
|
statement has no effect if no listing is generated. The default value is -1
|
|
(unlimited) but may be overridden by the <CODE>--pagelength</CODE> command line
|
|
option. Beware: Since ca65 is a one pass assembler, the listing is generated
|
|
after assembly is complete, you cannot use multiple line lengths with one
|
|
source. Instead, the value set with the last <CODE>.PAGELENGTH</CODE> is used.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.pagelength 66 ; Use 66 lines per listing page
|
|
|
|
.pagelength unlimited ; Unlimited page length
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".PC02"></A> <A NAME="ss11.82">11.82</A> <A HREF="#toc11.82"><CODE>.PC02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 65C02 instructions set. This instruction set includes all
|
|
6502 and 65SC02 instructions.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE>, <CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE>, <CODE>
|
|
<A HREF="#.P816">.P816</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PDTV"></A> <A NAME="ss11.83">11.83</A> <A HREF="#toc11.83"><CODE>.PDTV</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 6502DTV instruction set. This is a superset of the 6502
|
|
instruction set.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".POPCHARMAP"></A> <A NAME="ss11.84">11.84</A> <A HREF="#toc11.84"><CODE>.POPCHARMAP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Pop the last character mapping from the stack, and activate it.</P>
|
|
<P>This command will switch back to the character mapping that was last pushed onto the
|
|
character mapping stack using the <CODE>
|
|
<A HREF="#.PUSHCHARMAP">.PUSHCHARMAP</A></CODE>
|
|
command, and remove this entry from the stack.</P>
|
|
<P>The assembler will print an error message if the mappting stack is empty when
|
|
this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.CHARMAP">.CHARMAP</A></CODE>, <CODE>
|
|
<A HREF="#.PUSHCHARMAP">.PUSHCHARMAP</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".POPCPU"></A> <A NAME="ss11.85">11.85</A> <A HREF="#toc11.85"><CODE>.POPCPU</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Pop the last CPU setting from the stack, and activate it.</P>
|
|
<P>This command will switch back to the CPU that was last pushed onto the CPU
|
|
stack using the <CODE>
|
|
<A HREF="#.PUSHCPU">.PUSHCPU</A></CODE> command, and
|
|
remove this entry from the stack.</P>
|
|
<P>The assembler will print an error message if the CPU stack is empty when
|
|
this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.CPU">.CPU</A></CODE>, <CODE>
|
|
<A HREF="#.PUSHCPU">.PUSHCPU</A></CODE>, <CODE>
|
|
<A HREF="#.SETCPU">.SETCPU</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".POPSEG"></A> <A NAME="ss11.86">11.86</A> <A HREF="#toc11.86"><CODE>.POPSEG</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Pop the last pushed segment from the stack, and set it.</P>
|
|
<P>This command will switch back to the segment that was last pushed onto the
|
|
segment stack using the <CODE>
|
|
<A HREF="#.PUSHSEG">.PUSHSEG</A></CODE>
|
|
command, and remove this entry from the stack.</P>
|
|
<P>The assembler will print an error message if the segment stack is empty
|
|
when this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.PUSHSEG">.PUSHSEG</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PROC"></A> <A NAME="ss11.87">11.87</A> <A HREF="#toc11.87"><CODE>.PROC</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>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
|
|
<A HREF="#scopesyntax">explicit scope specification</A>. 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
|
|
<CODE>
|
|
<A HREF="#.ENDPROC">.ENDPROC</A></CODE> 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).</P>
|
|
<P>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.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.proc Clear ; Define Clear subroutine, start new level
|
|
lda #$00
|
|
L1: sta Mem,y ; L1 is local and does not cause a
|
|
; duplicate symbol error if used in other
|
|
; places
|
|
dey
|
|
bne L1 ; Reference local symbol
|
|
rts
|
|
.endproc ; Leave lexical level
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ENDPROC">.ENDPROC</A></CODE> and <CODE>
|
|
<A HREF="#.SCOPE">.SCOPE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PSC02"></A> <A NAME="ss11.88">11.88</A> <A HREF="#toc11.88"><CODE>.PSC02</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Enable the 65SC02 instructions set. This instruction set includes all
|
|
6502 instructions.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.P02">.P02</A></CODE>, <CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE>, <CODE>
|
|
<A HREF="#.P816">.P816</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PUSHCHARMAP"></A> <A NAME="ss11.89">11.89</A> <A HREF="#toc11.89"><CODE>.PUSHCHARMAP</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Push the currently active character mapping onto a stack. The stack has a size of 16
|
|
entries.</P>
|
|
<P><CODE>.PUSHCHARMAP</CODE> allows together with <CODE>
|
|
<A HREF="#.POPCHARMAP">.POPCHARMAP</A></CODE> to switch to another character mapping and to restore the old
|
|
character mapping later, without knowledge of the current mapping.</P>
|
|
<P>The assembler will print an error message if the character mapping stack is already full,
|
|
when this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.CHARMAP">.CHARMAP</A></CODE>, <CODE>
|
|
<A HREF="#.POPCHARMAP">.POPCHARMAP</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PUSHCPU"></A> <A NAME="ss11.90">11.90</A> <A HREF="#toc11.90"><CODE>.PUSHCPU</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Push the currently active CPU onto a stack. The stack has a size of 8
|
|
entries.</P>
|
|
<P><CODE>.PUSHCPU</CODE> allows together with <CODE>
|
|
<A HREF="#.POPCPU">.POPCPU</A></CODE> to switch to another CPU and to restore the old CPU
|
|
later, without knowledge of the current CPU setting.</P>
|
|
<P>The assembler will print an error message if the CPU stack is already full,
|
|
when this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.CPU">.CPU</A></CODE>, <CODE>
|
|
<A HREF="#.POPCPU">.POPCPU</A></CODE>, <CODE>
|
|
<A HREF="#.SETCPU">.SETCPU</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".PUSHSEG"></A> <A NAME="ss11.91">11.91</A> <A HREF="#toc11.91"><CODE>.PUSHSEG</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Push the currently active segment onto a stack. The entries on the stack
|
|
include the name of the segment and the segment type. The stack has a size
|
|
of 16 entries.</P>
|
|
<P><CODE>.PUSHSEG</CODE> allows together with <CODE>
|
|
<A HREF="#.POPSEG">.POPSEG</A></CODE>
|
|
to switch to another segment and to restore the old segment later, without
|
|
even knowing the name and type of the current segment.</P>
|
|
<P>The assembler will print an error message if the segment stack is already
|
|
full, when this command is issued.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.POPSEG">.POPSEG</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".REFERTO"></A> <A NAME="ss11.92">11.92</A> <A HREF="#toc11.92"><CODE>.REFERTO, .REFTO</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Mark a symbol as referenced.</P>
|
|
<P>It is useful in combination with the <CODE>
|
|
<A HREF="#.IFREF">.IFREF</A></CODE>
|
|
command. A subroutine with two entry points can be created. When the first
|
|
entry point is called, it sets some default value as an argument, and falls
|
|
through into the second entry point. <CODE>.REFERTO</CODE> helps to ensure that
|
|
the second part is included into binary when only the first entry point is
|
|
actually used from the code.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.ifref NegateValue ; If this subroutine is used
|
|
NegateValue: ; Define it
|
|
lda #0
|
|
sec
|
|
sbc Value
|
|
.ifref ResetValue ; If the ResetValue is also used
|
|
jmp SetValue ; Jump over it
|
|
.else
|
|
.refto SetValue ; Ensure that SetValue will be included
|
|
.endif
|
|
.endif
|
|
|
|
.ifref ResetValue ; If this subroutine is used
|
|
ResetValue: ; Define it
|
|
lda #0 ; Set a default value
|
|
.refto SetValue ; Ensure that SetValue will be included
|
|
.endif
|
|
|
|
.ifref SetValue ; If this or previous subroutine is used
|
|
SetValue:
|
|
sta Value
|
|
rts
|
|
.endif
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".RELOC"></A> <A NAME="ss11.93">11.93</A> <A HREF="#toc11.93"><CODE>.RELOC</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch back to relocatable mode. See the <CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> command.</P>
|
|
|
|
|
|
<H2><A NAME=".REPEAT"></A> <A NAME="ss11.94">11.94</A> <A HREF="#toc11.94"><CODE>.REPEAT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Repeat all commands between <CODE>.REPEAT</CODE> and <CODE>
|
|
<A HREF="#.ENDREPEAT">.ENDREPEAT</A></CODE> constant number of times. The command is followed by
|
|
a constant expression that tells how many times the commands in the body
|
|
should get repeated. Optionally, a comma and an identifier may be specified.
|
|
If this identifier is found in the body of the repeat statement, it is
|
|
replaced by the current repeat count (starting with zero for the first time
|
|
the body is repeated).</P>
|
|
<P><CODE>.REPEAT</CODE> statements may be nested. If you use the same repeat count
|
|
identifier for a nested <CODE>.REPEAT</CODE> statement, the one from the inner
|
|
level will be used, not the one from the outer level.</P>
|
|
<P>Example:</P>
|
|
<P>The following macro will emit a string that is "encrypted" in that all
|
|
characters of the string are XORed by the value $55.</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro Crypt Arg
|
|
.repeat .strlen(Arg), I
|
|
.byte .strat(Arg, I) ^ $55
|
|
.endrep
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ENDREPEAT">.ENDREPEAT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".RES"></A> <A NAME="ss11.95">11.95</A> <A HREF="#toc11.95"><CODE>.RES</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Reserve storage. The command is followed by one or two constant
|
|
expressions. The first one is mandatory and defines, how many bytes of
|
|
storage should be defined. The second, optional expression must by a
|
|
constant byte value that will be used as value of the data. If there
|
|
is no fill value given, the linker will use the value defined in the
|
|
linker configuration file (default: zero).</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Reserve 12 bytes of memory with value $AA
|
|
.res 12, $AA
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".RODATA"></A> <A NAME="ss11.96">11.96</A> <A HREF="#toc11.96"><CODE>.RODATA</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to the RODATA segment. The name of the RODATA segment is always
|
|
"RODATA", so this is a shortcut for</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "RODATA"
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The RODATA segment is a segment that is used by the compiler for
|
|
readonly data like string constants.</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.SEGMENT">.SEGMENT</A></CODE> command.</P>
|
|
|
|
|
|
<H2><A NAME=".SCOPE"></A> <A NAME="ss11.97">11.97</A> <A HREF="#toc11.97"><CODE>.SCOPE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<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
|
|
<A HREF="#scopesyntax">explicit scope specification</A>. 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 <CODE>
|
|
<A HREF="#.ENDSCOPE">.ENDSCOPE</A></CODE> 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).</P>
|
|
<P>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.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.scope Error ; Start new scope named Error
|
|
None = 0 ; No error
|
|
File = 1 ; File error
|
|
Parse = 2 ; Parse error
|
|
.endscope ; Close lexical level
|
|
|
|
...
|
|
lda #Error::File ; Use symbol from scope Error
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.ENDSCOPE">.ENDSCOPE</A></CODE> and <CODE>
|
|
<A HREF="#.PROC">.PROC</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".SEGMENT"></A> <A NAME="ss11.98">11.98</A> <A HREF="#toc11.98"><CODE>.SEGMENT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to another segment. Code and data is always emitted into a
|
|
segment, that is, a named section of data. The default segment is
|
|
"CODE". There may be up to 254 different segments per object file
|
|
(and up to 65534 per executable). There are shortcut commands for
|
|
the most common segments ("ZEROPAGE", "CODE", "RODATA", "DATA", and "BSS").</P>
|
|
<P>The command is followed by a string containing the segment name (there are
|
|
some constraints for the name - as a rule of thumb use only those segment
|
|
names that would also be valid identifiers). There may also be an optional
|
|
address size separated by a colon. See the section covering <CODE>
|
|
<A HREF="#address-sizes">address sizes</A></CODE> for more information.</P>
|
|
<P>The default address size for a segment depends on the memory model specified
|
|
on the command line. The default is "absolute", which means that you don't
|
|
have to use an address size modifier in most cases.</P>
|
|
<P>"absolute" means that the is a segment with 16 bit (absolute) addressing.
|
|
That is, the segment will reside somewhere in core memory outside the zero
|
|
page. "zeropage" (8 bit) means that the segment will be placed in the zero
|
|
page and direct (short) addressing is possible for data in this segment.</P>
|
|
<P>Beware: Only labels in a segment with the zeropage attribute are marked
|
|
as reachable by short addressing. The '*' (PC counter) operator will
|
|
work as in other segments and will create absolute variable values.</P>
|
|
<P>Please note that a segment cannot have two different address sizes. A
|
|
segment specified as zeropage cannot be declared as being absolute later.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "ROM2" ; Switch to ROM2 segment
|
|
.segment "ZP2": zeropage ; New direct segment
|
|
.segment "ZP2" ; Ok, will use last attribute
|
|
.segment "ZP2": absolute ; Error, redecl mismatch
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.BSS">.BSS</A></CODE>, <CODE>
|
|
<A HREF="#.CODE">.CODE</A></CODE>, <CODE>
|
|
<A HREF="#.DATA">.DATA</A></CODE>, <CODE>
|
|
<A HREF="#.RODATA">.RODATA</A></CODE>, and <CODE>
|
|
<A HREF="#.ZEROPAGE">.ZEROPAGE</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".SET"></A> <A NAME="ss11.99">11.99</A> <A HREF="#toc11.99"><CODE>.SET</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P><CODE>.SET</CODE> is used to assign a value to a variable. See
|
|
<A HREF="#variables">Numeric variables</A> for a full description.</P>
|
|
|
|
|
|
<H2><A NAME=".SETCPU"></A> <A NAME="ss11.100">11.100</A> <A HREF="#toc11.100"><CODE>.SETCPU</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch the CPU instruction set. The command is followed by a string that
|
|
specifies the CPU. Possible values are those that can also be supplied to
|
|
the <CODE>
|
|
<A HREF="#option--cpu">--cpu</A></CODE> command line option,
|
|
namely: 6502, 6502X, 6502DTV, 65SC02, 65C02, 65816, 4510 and HuC6280.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.CPU">.CPU</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.IFP02">.IFP02</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.IFPDTV">.IFPDTV</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.IFP816">.IFP816</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.IFPC02">.IFPC02</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.IFPSC02">.IFPSC02</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.P02">.P02</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.P816">.P816</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.P4510">.P4510</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.PC02">.PC02</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.PSC02">.PSC02</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".SMART"></A> <A NAME="ss11.101">11.101</A> <A HREF="#toc11.101"><CODE>.SMART</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch on or off smart mode. The command can be followed by a '+' or '-'
|
|
character to switch the option on or off respectively. The default 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.</P>
|
|
<P>In smart mode the assembler will do the following:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>Track usage of the <CODE>REP</CODE> and <CODE>SEP</CODE> 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 <CODE>.Inn</CODE> and <CODE>.Ann</CODE>
|
|
instructions to tell the assembler about the current settings.</LI>
|
|
<LI>In 65816 mode, if the <CODE>
|
|
<A HREF="#long_jsr_jmp_rts">long_jsr_jmp_rts</A></CODE> feature is enabled,
|
|
smart mode will replace a <CODE>RTS</CODE> instruction by <CODE>RTL</CODE> if it is
|
|
used within a procedure declared as <CODE>far</CODE>, or if the procedure has
|
|
no explicit address specification, but it is <CODE>far</CODE> because of the
|
|
memory model used.</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.smart ; Be smart
|
|
.smart - ; Stop being smart
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.A16">.A16</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.A8">.A8</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.I16">.I16</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.I8">.I8</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".STRUCT"></A> <A NAME="ss11.102">11.102</A> <A HREF="#toc11.102"><CODE>.STRUCT</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Starts a struct definition. Structs are covered in a separate section named
|
|
<A HREF="#structs">"Structs and unions"</A>.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ENDSTRUCT">.ENDSTRUCT</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.ENDUNION">.ENDUNION</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.UNION">.UNION</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".TAG"></A> <A NAME="ss11.103">11.103</A> <A HREF="#toc11.103"><CODE>.TAG</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Allocate space for a struct or union. This is equivalent to
|
|
<CODE>
|
|
<A HREF="#.RES">.RES</A></CODE> with the
|
|
<CODE>
|
|
<A HREF="#.SIZEOF">.SIZEOF</A></CODE> of a struct.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Point
|
|
xcoord .word
|
|
ycoord .word
|
|
.endstruct
|
|
|
|
.bss
|
|
.tag Point ; Allocate 4 bytes
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See:
|
|
<A HREF="#structs">"Structs and unions"</A></P>
|
|
|
|
<H2><A NAME=".UNDEFINE"></A> <A NAME="ss11.104">11.104</A> <A HREF="#toc11.104"><CODE>.UNDEF, .UNDEFINE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Delete a define style macro definition. The command is followed by an
|
|
identifier which specifies the name of the macro to delete. Macro
|
|
replacement is switched of when reading the token following the command
|
|
(otherwise the macro name would be replaced by its replacement list).</P>
|
|
<P>See also the <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> command and
|
|
section
|
|
<A HREF="#macros">Macros</A>.</P>
|
|
|
|
|
|
<H2><A NAME=".UNION"></A> <A NAME="ss11.105">11.105</A> <A HREF="#toc11.105"><CODE>.UNION</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Starts a union definition. Unions are covered in a separate section named
|
|
<A HREF="#structs">"Structs and unions"</A>.</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ENDSTRUCT">.ENDSTRUCT</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.ENDUNION">.ENDUNION</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.STRUCT">.STRUCT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".WARNING"></A> <A NAME="ss11.106">11.106</A> <A HREF="#toc11.106"><CODE>.WARNING</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Force an assembly warning. The assembler will output a warning message
|
|
preceded by "User warning". This warning will always be output, even if
|
|
other warnings are disabled with the <CODE>
|
|
<A HREF="#option-W">-W0</A></CODE>
|
|
command line option.</P>
|
|
<P>This command may be used to output possible problems when assembling
|
|
the source file.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro jne target
|
|
.local L1
|
|
.ifndef target
|
|
.warning "Forward jump in jne, cannot optimize!"
|
|
beq L1
|
|
jmp target
|
|
L1:
|
|
.else
|
|
...
|
|
.endif
|
|
.endmacro
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>See also: <CODE>
|
|
<A HREF="#.ERROR">.ERROR</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.FATAL">.FATAL</A></CODE>,
|
|
<CODE>
|
|
<A HREF="#.OUT">.OUT</A></CODE></P>
|
|
|
|
|
|
<H2><A NAME=".WORD"></A> <A NAME="ss11.107">11.107</A> <A HREF="#toc11.107"><CODE>.WORD</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Define word sized data. Must be followed by a sequence of (word ranged,
|
|
but not necessarily constant) expressions.</P>
|
|
<P>Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.word $0D00, $AF13, _Clear
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME=".ZEROPAGE"></A> <A NAME="ss11.108">11.108</A> <A HREF="#toc11.108"><CODE>.ZEROPAGE</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>Switch to the ZEROPAGE segment and mark it as direct (zeropage) segment.
|
|
The name of the ZEROPAGE segment is always "ZEROPAGE", so this is a
|
|
shortcut for</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.segment "ZEROPAGE": zeropage
|
|
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Because of the "zeropage" attribute, labels declared in this segment are
|
|
addressed using direct addressing mode if possible. You <EM>must</EM> instruct
|
|
the linker to place this segment somewhere in the address range 0..$FF
|
|
otherwise you will get errors.</P>
|
|
<P>See: <CODE>
|
|
<A HREF="#.SEGMENT">.SEGMENT</A></CODE></P>
|
|
|
|
|
|
|
|
<H2><A NAME="macros"></A> <A NAME="s12">12.</A> <A HREF="#toc12">Macros</A></H2>
|
|
|
|
|
|
|
|
|
|
<H2><A NAME="ss12.1">12.1</A> <A HREF="#toc12.1">Introduction</A>
|
|
</H2>
|
|
|
|
|
|
<P>Macros may be thought of as "parametrized super instructions". Macros are
|
|
sequences of tokens that have a name. If that name is used in the source
|
|
file, the macro is "expanded", that is, it is replaced by the tokens that
|
|
were specified when the macro was defined.</P>
|
|
|
|
|
|
<H2><A NAME="ss12.2">12.2</A> <A HREF="#toc12.2">Macros without parameters</A>
|
|
</H2>
|
|
|
|
|
|
<P>In its simplest form, a macro does not have parameters. Here's an
|
|
example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro asr ; Arithmetic shift right
|
|
cmp #$80 ; Put bit 7 into carry
|
|
ror ; Rotate right with carry
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The macro above consists of two real instructions, that are inserted into
|
|
the code, whenever the macro is expanded. Macro expansion is simply done
|
|
by using the name, like this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda $2010
|
|
asr
|
|
sta $2010
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss12.3">12.3</A> <A HREF="#toc12.3">Parametrized macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>When using macro parameters, macros can be even more useful:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro inc16 addr
|
|
clc
|
|
lda addr
|
|
adc #<$0001
|
|
sta addr
|
|
lda addr+1
|
|
adc #>$0001
|
|
sta addr+1
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>When calling the macro, you may give a parameter, and each occurrence of
|
|
the name "addr" in the macro definition will be replaced by the given
|
|
parameter. So</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
inc16 $1000
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>will be expanded to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
clc
|
|
lda $1000
|
|
adc #<$0001
|
|
sta $1000
|
|
lda $1000+1
|
|
adc #>$0001
|
|
sta $1000+1
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>A macro may have more than one parameter, in this case, the parameters
|
|
are separated by commas. You are free to give less parameters than the
|
|
macro actually takes in the definition. You may also leave intermediate
|
|
parameters empty. Empty parameters are replaced by empty space (that is,
|
|
they are removed when the macro is expanded). If you have a look at our
|
|
macro definition above, you will see, that replacing the "addr" parameter
|
|
by nothing will lead to wrong code in most lines.</P>
|
|
<P>The names "a", "x" and "y" should be avoided for macro parameters, as these
|
|
will usually conflict with the 6502 registers.</P>
|
|
<P>For writing macros with a variable parameter list, control commands are
|
|
available:</P>
|
|
<P><CODE>
|
|
<A HREF="#.IFBLANK">.IFBLANK</A></CODE> tests the rest of the line and
|
|
returns true, if there are any tokens on the remainder of the line. Since
|
|
empty parameters are replaced by nothing, this may be used to test if a given
|
|
parameter is empty. <CODE>
|
|
<A HREF="#.IFNBLANK">.IFNBLANK</A></CODE> tests the
|
|
opposite.</P>
|
|
<P>Look at this example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro ldaxy i, j, k
|
|
.ifnblank i
|
|
lda #i
|
|
.endif
|
|
.ifnblank j
|
|
ldx #j
|
|
.endif
|
|
.ifnblank k
|
|
ldy #k
|
|
.endif
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>That macro may be called as follows:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
ldaxy 1, 2, 3 ; Load all three registers
|
|
|
|
ldaxy 1, , 3 ; Load only a and y
|
|
|
|
ldaxy , , 3 ; Load y only
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>There's another helper command for determining which macro parameters are
|
|
valid: <CODE>
|
|
<A HREF="#.PARAMCOUNT">.PARAMCOUNT</A></CODE>. That command is
|
|
replaced by the parameter count given, <EM>including</EM> explicitly empty
|
|
parameters:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
ldaxy 1 ; .PARAMCOUNT = 1
|
|
ldaxy 1,,3 ; .PARAMCOUNT = 3
|
|
ldaxy 1,2 ; .PARAMCOUNT = 2
|
|
ldaxy 1, ; .PARAMCOUNT = 2
|
|
ldaxy 1,2,3 ; .PARAMCOUNT = 3
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Macro parameters may optionally be enclosed into curly braces. This allows the
|
|
inclusion of tokens that would otherwise terminate the parameter (the comma in
|
|
case of a macro parameter).</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro foo arg1, arg2
|
|
...
|
|
.endmacro
|
|
|
|
foo ($00,x) ; Two parameters passed
|
|
foo {($00,x)} ; One parameter passed
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In the first case, the macro is called with two parameters: '<CODE>($00</CODE>'
|
|
and '<CODE>x)</CODE>'. The comma is not passed to the macro, because it is part of the
|
|
calling sequence, not the parameters.</P>
|
|
<P>In the second case, '<CODE>($00,x)</CODE>' is passed to the macro; this time,
|
|
including the comma.</P>
|
|
|
|
|
|
<H2><A NAME="ss12.4">12.4</A> <A HREF="#toc12.4">Detecting parameter types</A>
|
|
</H2>
|
|
|
|
|
|
<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 <CODE>
|
|
<A HREF="#.MATCH">.MATCH</A></CODE> and <CODE>
|
|
<A HREF="#.XMATCH">.XMATCH</A></CODE>
|
|
functions will allow you to do exactly this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.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
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Using the <CODE>
|
|
<A HREF="#.MATCH">.MATCH</A></CODE> 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. Please note how the curly braces are used to enclose parameters to
|
|
pseudo functions handling token lists. This is necessary, because the token
|
|
lists may include commas or parens, which would be treated by the assembler
|
|
as end-of-list.</P>
|
|
<P>The macro can be used as</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
foo: .word $5678
|
|
...
|
|
ldax #$1234 ; X=$12, A=$34
|
|
...
|
|
ldax foo ; X=$56, A=$78
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss12.5">12.5</A> <A HREF="#toc12.5">Recursive macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>Macros may be used recursively:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro push r1, r2, r3
|
|
lda r1
|
|
pha
|
|
.ifnblank r2
|
|
push r2, r3
|
|
.endif
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>There's also a special macro command to help with writing recursive macros:
|
|
<CODE>
|
|
<A HREF="#.EXITMACRO">.EXITMACRO</A></CODE>. That command will stop macro
|
|
expansion immediately:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro push r1, r2, r3, r4, r5, r6, r7
|
|
.ifblank r1
|
|
; First parameter is empty
|
|
.exitmacro
|
|
.else
|
|
lda r1
|
|
pha
|
|
.endif
|
|
push r2, r3, r4, r5, r6, r7
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>When expanding that macro, the expansion will push all given parameters
|
|
until an empty one is encountered. The macro may be called like this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
push $20, $21, $32 ; Push 3 ZP locations
|
|
push $21 ; Push one ZP location
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss12.6">12.6</A> <A HREF="#toc12.6">Local symbols inside macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>Now, with recursive macros, <CODE>
|
|
<A HREF="#.IFBLANK">.IFBLANK</A></CODE> and
|
|
<CODE>
|
|
<A HREF="#.PARAMCOUNT">.PARAMCOUNT</A></CODE>, what else do you need?
|
|
Have a look at the inc16 macro above. Here is it again:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro inc16 addr
|
|
clc
|
|
lda addr
|
|
adc #<$0001
|
|
sta addr
|
|
lda addr+1
|
|
adc #>$0001
|
|
sta addr+1
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>If you have a closer look at the code, you will notice, that it could be
|
|
written more efficiently, like this:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro inc16 addr
|
|
inc addr
|
|
bne Skip
|
|
inc addr+1
|
|
Skip:
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>But imagine what happens, if you use this macro twice? Since the label "Skip"
|
|
has the same name both times, you get a "duplicate symbol" error. Without a
|
|
way to circumvent this problem, macros are not as useful, as they could be.
|
|
One possible solution is the command <CODE>
|
|
<A HREF="#.LOCAL">.LOCAL</A></CODE>.
|
|
It declares one or more symbols as local to the macro expansion. The names of
|
|
local variables are replaced by a unique name in each separate macro
|
|
expansion. So we can solve the problem above by using <CODE>.LOCAL</CODE>:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro inc16 addr
|
|
.local Skip ; Make Skip a local symbol
|
|
inc addr
|
|
bne Skip
|
|
inc addr+1
|
|
Skip: ; Not visible outside
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Another solution is of course to start a new lexical block inside the macro
|
|
that hides any labels:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro inc16 addr
|
|
.proc
|
|
inc addr
|
|
bne Skip
|
|
inc addr+1
|
|
Skip:
|
|
.endproc
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss12.7">12.7</A> <A HREF="#toc12.7">C style macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>Starting with version 2.5 of the assembler, there is a second macro type
|
|
available: C style macros using the <CODE>.DEFINE</CODE> directive. These macros are
|
|
similar to the classic macro type described above, but behaviour is sometimes
|
|
different:</P>
|
|
<P>
|
|
<UL>
|
|
<LI> Macros defined with <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> may not
|
|
span more than a line. You may use line continuation (see <CODE>
|
|
<A HREF="#line_continuations">line_continuations</A></CODE>) to spread the
|
|
definition over more than one line for increased readability, but the
|
|
macro itself may not contain an end-of-line token.
|
|
</LI>
|
|
<LI> Macros defined with <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> share
|
|
the name space with classic macros, but they are detected and replaced
|
|
at the scanner level. While classic macros may be used in every place,
|
|
where a mnemonic or other directive is allowed, <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> style macros are allowed anywhere in a line. So
|
|
they are more versatile in some situations.
|
|
</LI>
|
|
<LI> <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> style macros may take
|
|
parameters. While classic macros may have empty parameters, this is
|
|
not true for <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> style macros.
|
|
For this macro type, the number of actual parameters must match
|
|
exactly the number of formal parameters.
|
|
|
|
To make this possible, formal parameters are enclosed in parentheses when
|
|
defining the macro. If there are no parameters, the empty parentheses may
|
|
be omitted.
|
|
</LI>
|
|
<LI> Since <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> style macros may not
|
|
contain end-of-line tokens, there are things that cannot be done. They
|
|
may not contain several processor instructions for example. So, while
|
|
some things may be done with both macro types, each type has special
|
|
usages. The types complement each other.
|
|
</LI>
|
|
<LI> Parentheses work differently from C macros.
|
|
The common practice of wrapping C macros in parentheses may cause
|
|
unintended problems here, such as accidentally implying an
|
|
indirect addressing mode. While the definition of a macro requires
|
|
parentheses around its argument list, when invoked they should not be
|
|
included.
|
|
</LI>
|
|
</UL>
|
|
</P>
|
|
<P>Let's look at a few examples to make the advantages and disadvantages
|
|
clear.</P>
|
|
<P>To emulate assemblers that use "<CODE>EQU</CODE>" instead of "<CODE>=</CODE>" you may use the
|
|
following <CODE>.DEFINE</CODE>:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define EQU =
|
|
|
|
foo EQU $1234 ; This is accepted now
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>You may use the directive to define string constants used elsewhere:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; Define the version number
|
|
.define VERSION "12.3a"
|
|
|
|
; ... and use it
|
|
.asciiz VERSION
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Macros with parameters may also be useful:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define DEBUG(message) .out message
|
|
|
|
DEBUG "Assembling include file #3"
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Note that, while formal parameters have to be placed in parentheses,
|
|
the actual argument used when invoking the macro should not be.
|
|
The invoked arguments are separated by commas only; if parentheses are
|
|
used by accident, they will become part of the replaced token.</P>
|
|
<P>If you wish to have an expression follow the macro invocation, the
|
|
last parameter can be enclosed in curly braces {} to indicate the end of that
|
|
argument.</P>
|
|
<P>Examples:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define COMBINE(ta,tb,tc) ta+tb*10+tc*100
|
|
|
|
.word COMBINE 5,6,7 ; 5+6*10+7*100 = 765
|
|
.word COMBINE(5,6,7) ; (5+6*10+7)*100 = 7200 ; incorrect use of parentheses
|
|
.word COMBINE 5,6,7+1 ; 5+6*10+7+1*100 = 172
|
|
.word COMBINE 5,6,{7}+1 ; 5+6*10+7*100+1 = 766 ; {} encloses the argument
|
|
.word COMBINE 5,6-2,7 ; 5+6-2*10+7*100 = 691
|
|
.word COMBINE 5,(6-2),7 ; 5+(6-2)*10+7*100 = 745
|
|
.word COMBINE 5,6,7+COMBINE 0,1,2 ; 5+6*10+7+0+1*10+2*100*100 = 20082
|
|
.word COMBINE 5,6,{7}+COMBINE 0,1,2 ; 5+6*10+7*100+0+1*10+2*100 = 975
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>With C macros it is common to enclose the results in parentheses to
|
|
prevent unintended interactions with the text of the arguments, but
|
|
additional care must be taken in this assembly context where parentheses
|
|
may alter the meaning of a statement. In particular, indirect addressing modes
|
|
may be accidentally implied:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define DUO(ta,tb) (ta+(tb*10))
|
|
|
|
lda DUO(5,4), Y ; LDA (indirect), Y
|
|
lda 0+DUO(5,4), Y ; LDA absolute indexed, Y
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss12.8">12.8</A> <A HREF="#toc12.8">Characters in macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>When using the
|
|
<A HREF="#option-t">-t</A> option, characters are translated
|
|
into the target character set of the specific machine. However, this happens
|
|
as late as possible. This means that strings are translated if they are part
|
|
of a <CODE>
|
|
<A HREF="#.BYTE">.BYTE</A></CODE> or <CODE>
|
|
<A HREF="#.ASCIIZ">.ASCIIZ</A></CODE> command. Characters are translated as soon as they are
|
|
used as part of an expression.</P>
|
|
<P>This behaviour is very intuitive outside of macros but may be confusing when
|
|
doing more complex macros. If you compare characters against numeric values,
|
|
be sure to take the translation into account.</P>
|
|
|
|
|
|
<H2><A NAME="ss12.9">12.9</A> <A HREF="#toc12.9">Deleting macros</A>
|
|
</H2>
|
|
|
|
|
|
<P>Macros can be deleted. This will not work if the macro that should be deleted
|
|
is currently expanded as in the following non-working example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro notworking
|
|
.delmacro notworking
|
|
.endmacro
|
|
|
|
notworking ; Will not work
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The commands to delete classic and define style macros differ. Classic macros
|
|
can be deleted by use of <CODE>
|
|
<A HREF="#.DELMACRO">.DELMACRO</A></CODE>, while
|
|
for <CODE>
|
|
<A HREF="#.DEFINE">.DEFINE</A></CODE> style macros, <CODE>
|
|
<A HREF="#.UNDEFINE">.UNDEFINE</A></CODE> must be used. Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.define value 1
|
|
.macro mac
|
|
.byte 2
|
|
.endmacro
|
|
|
|
.byte value ; Emit one byte with value 1
|
|
mac ; Emit another byte with value 2
|
|
|
|
.undefine value
|
|
.delmacro mac
|
|
|
|
.byte value ; Error: Unknown identifier
|
|
mac ; Error: Missing ":"
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>A separate command for <CODE>.DEFINE</CODE> style macros was necessary, because
|
|
the name of such a macro is replaced by its replacement list on a very low
|
|
level. To get the actual name, macro replacement has to be switched off when
|
|
reading the argument to <CODE>.UNDEFINE</CODE>. This does also mean that the
|
|
argument to <CODE>.UNDEFINE</CODE> is not allowed to come from another
|
|
<CODE>.DEFINE</CODE>. All this is not necessary for classic macros, so having two
|
|
different commands increases flexibility.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="macropackages"></A> <A NAME="s13">13.</A> <A HREF="#toc13">Macro packages</A></H2>
|
|
|
|
|
|
<P>Using the <CODE>
|
|
<A HREF="#.MACPACK">.MACPACK</A></CODE> directive, predefined
|
|
macro packages may be included with just one command. Available macro packages
|
|
are:</P>
|
|
|
|
|
|
<H2><A NAME="ss13.1">13.1</A> <A HREF="#toc13.1"><CODE>.MACPACK generic</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines macros that are useful in almost any program.
|
|
Currently defined macros are:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro add Arg ; add without carry
|
|
clc
|
|
adc Arg
|
|
.endmacro
|
|
|
|
.macro sub Arg ; subtract without borrow
|
|
sec
|
|
sbc Arg
|
|
.endmacro
|
|
|
|
.macro bge Arg ; branch on greater-than or equal
|
|
bcs Arg
|
|
.endmacro
|
|
|
|
.macro blt Arg ; branch on less-than
|
|
bcc Arg
|
|
.endmacro
|
|
|
|
.macro bgt Arg ; branch on greater-than
|
|
.local L
|
|
beq L
|
|
bcs Arg
|
|
L:
|
|
.endmacro
|
|
|
|
.macro ble Arg ; branch on less-than or equal
|
|
beq Arg
|
|
bcc Arg
|
|
.endmacro
|
|
|
|
.macro bnz Arg ; branch on not zero
|
|
bne Arg
|
|
.endmacro
|
|
|
|
.macro bze Arg ; branch on zero
|
|
beq Arg
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss13.2">13.2</A> <A HREF="#toc13.2"><CODE>.MACPACK longbranch</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines long conditional jumps. They are named like the
|
|
short counterpart but with the 'b' replaced by a 'j'. Here is a sample
|
|
definition for the "<CODE>jeq</CODE>" macro, the other macros are built using the same
|
|
scheme:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.macro jeq Target
|
|
.if .def(Target) .and ((*+2)-(Target) <= 127)
|
|
beq Target
|
|
.else
|
|
bne *+5
|
|
jmp Target
|
|
.endif
|
|
.endmacro
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>All macros expand to a short branch, if the label is already defined (back
|
|
jump) and is reachable with a short jump. Otherwise the macro expands to a
|
|
conditional branch with the branch condition inverted, followed by an absolute
|
|
jump to the actual branch target.</P>
|
|
<P>The package defines the following macros:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
jeq, jne, jmi, jpl, jcs, jcc, jvs, jvc
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME="ss13.3">13.3</A> <A HREF="#toc13.3"><CODE>.MACPACK apple2</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines a macro named <CODE>scrcode</CODE>. It takes a string
|
|
as argument and places this string into memory translated into screen codes.</P>
|
|
|
|
|
|
<H2><A NAME="ss13.4">13.4</A> <A HREF="#toc13.4"><CODE>.MACPACK atari</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines a macro named <CODE>scrcode</CODE>. It takes a string
|
|
as argument and places this string into memory translated into screen codes.</P>
|
|
|
|
|
|
<H2><A NAME="ss13.5">13.5</A> <A HREF="#toc13.5"><CODE>.MACPACK cbm</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines a macro named <CODE>scrcode</CODE>. It takes a string
|
|
as argument and places this string into memory translated into screen codes.</P>
|
|
|
|
|
|
<H2><A NAME="ss13.6">13.6</A> <A HREF="#toc13.6"><CODE>.MACPACK cpu</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package does not define any macros but constants used to examine
|
|
the value read from the <CODE>
|
|
<A HREF="#.CPU">.CPU</A></CODE> pseudo variable. For
|
|
each supported CPU a constant similar to</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
CPU_6502
|
|
CPU_65SC02
|
|
CPU_65C02
|
|
CPU_65816
|
|
CPU_SWEET16
|
|
CPU_HUC6280
|
|
CPU_4510
|
|
CPU_6502DTV
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>is defined. These constants may be used to determine the exact type of the
|
|
currently enabled CPU. In addition to that, for each CPU instruction set,
|
|
another constant is defined:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
CPU_ISET_6502
|
|
CPU_ISET_65SC02
|
|
CPU_ISET_65C02
|
|
CPU_ISET_65816
|
|
CPU_ISET_SWEET16
|
|
CPU_ISET_HUC6280
|
|
CPU_ISET_4510
|
|
CPU_ISET_6502DTV
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>The value read from the <CODE>
|
|
<A HREF="#.CPU">.CPU</A></CODE> pseudo variable may
|
|
be checked with <CODE>
|
|
<A HREF="#operators">.BITAND</A></CODE> to determine if the
|
|
currently enabled CPU supports a specific instruction set. For example the
|
|
65C02 supports all instructions of the 65SC02 CPU, so it has the
|
|
<CODE>CPU_ISET_65SC02</CODE> bit set in addition to its native <CODE>CPU_ISET_65C02</CODE>
|
|
bit. Using</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.if (.cpu .bitand CPU_ISET_65SC02)
|
|
lda (sp)
|
|
.else
|
|
ldy #$00
|
|
lda (sp),y
|
|
.endif
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>it is possible to determine if the</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda (sp)
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>instruction is supported, which is the case for the 65SC02, 65C02 and 65816
|
|
CPUs (the latter two are upwards compatible to the 65SC02).</P>
|
|
|
|
|
|
<H2><A NAME="ss13.7">13.7</A> <A HREF="#toc13.7"><CODE>.MACPACK module</CODE></A>
|
|
</H2>
|
|
|
|
|
|
<P>This macro package defines a macro named <CODE>module_header</CODE>. It takes an
|
|
identifier as argument and is used to define the header of a module both
|
|
in the dynamic and static variant.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="predefined-constants"></A> <A NAME="s14">14.</A> <A HREF="#toc14">Predefined constants</A></H2>
|
|
|
|
|
|
<P>For better orthogonality, the assembler defines similar symbols as the
|
|
compiler, depending on the target system selected:</P>
|
|
<P>
|
|
<UL>
|
|
<LI><CODE>__APPLE2__</CODE> - Target system is <CODE>apple2</CODE> or <CODE>apple2enh</CODE></LI>
|
|
<LI><CODE>__APPLE2ENH__</CODE> - Target system is <CODE>apple2enh</CODE></LI>
|
|
<LI><CODE>__ATARI2600__</CODE> - Target system is <CODE>atari2600</CODE></LI>
|
|
<LI><CODE>__ATARI5200__</CODE> - Target system is <CODE>atari5200</CODE></LI>
|
|
<LI><CODE>__ATARI7800__</CODE> - Target system is <CODE>atari7800</CODE></LI>
|
|
<LI><CODE>__ATARI__</CODE> - Target system is <CODE>atari</CODE> or <CODE>atarixl</CODE></LI>
|
|
<LI><CODE>__ATARIXL__</CODE> - Target system is <CODE>atarixl</CODE></LI>
|
|
<LI><CODE>__ATMOS__</CODE> - Target system is <CODE>atmos</CODE></LI>
|
|
<LI><CODE>__BBC__</CODE> - Target system is <CODE>bbc</CODE></LI>
|
|
<LI><CODE>__C128__</CODE> - Target system is <CODE>c128</CODE></LI>
|
|
<LI><CODE>__C16__</CODE> - Target system is <CODE>c16</CODE> or <CODE>plus4</CODE></LI>
|
|
<LI><CODE>__C64__</CODE> - Target system is <CODE>c64</CODE></LI>
|
|
<LI><CODE>__CBM__</CODE> - Target is a Commodore or Commodore-alike system</LI>
|
|
<LI><CODE>__CBM510__</CODE> - Target system is <CODE>cbm510</CODE></LI>
|
|
<LI><CODE>__CBM610__</CODE> - Target system is <CODE>cbm610</CODE></LI>
|
|
<LI><CODE>__CX16__</CODE> - Target system is <CODE>cx16</CODE></LI>
|
|
<LI><CODE>__GEOS__</CODE> - Target is a GEOS system</LI>
|
|
<LI><CODE>__GEOS_APPLE__</CODE> - Target system is <CODE>geos-apple</CODE></LI>
|
|
<LI><CODE>__GEOS_CBM__</CODE> - Target system is <CODE>geos-cbm</CODE></LI>
|
|
<LI><CODE>__LUNIX__</CODE> - Target system is <CODE>lunix</CODE></LI>
|
|
<LI><CODE>__LYNX__</CODE> - Target system is <CODE>lynx</CODE></LI>
|
|
<LI><CODE>__NES__</CODE> - Target system is <CODE>nes</CODE></LI>
|
|
<LI><CODE>__OSIC1P__</CODE> - Target system is <CODE>osic1p</CODE></LI>
|
|
<LI><CODE>__PET__</CODE> - Target system is <CODE>pet</CODE></LI>
|
|
<LI><CODE>__PLUS4__</CODE> - Target system is <CODE>plus4</CODE></LI>
|
|
<LI><CODE>__SIM6502__</CODE> - Target system is <CODE>sim6502</CODE></LI>
|
|
<LI><CODE>__SIM65C02__</CODE> - Target system is <CODE>sim65c02</CODE></LI>
|
|
<LI><CODE>__SUPERVISION__</CODE> - Target system is <CODE>supervision</CODE></LI>
|
|
<LI><CODE>__SYM1__</CODE> - Target system is <CODE>sym1</CODE></LI>
|
|
<LI><CODE>__VIC20__</CODE> - Target system is <CODE>vic20</CODE></LI>
|
|
</UL>
|
|
</P>
|
|
|
|
|
|
|
|
<H2><A NAME="structs"></A> <A NAME="s15">15.</A> <A HREF="#toc15">Structs and unions</A></H2>
|
|
|
|
|
|
|
|
<H2><A NAME="ss15.1">15.1</A> <A HREF="#toc15.1">Structs and unions Overview</A>
|
|
</H2>
|
|
|
|
|
|
<P>Structs and unions are special forms of
|
|
<A HREF="#scopes">scopes</A>. They
|
|
are, to some degree, comparable to their C counterparts. Both have a list of
|
|
members. Each member allocates storage, and optionally may have a name.</P>
|
|
<P>Each named member has a constant value equal to the storage offset from the
|
|
beginning of the structure. In the case of a union, all members are placed at
|
|
the same offset, typically 0.</P>
|
|
<P>Each named member also has a storage size which can be accessed with the
|
|
<CODE>
|
|
<A HREF="#.SIZEOF">.SIZEOF</A></CODE> operator. The struct or union itself
|
|
also has a <CODE>.SIZEOF</CODE> indicating its total storage size.</P>
|
|
|
|
<H2><A NAME="ss15.2">15.2</A> <A HREF="#toc15.2">Declaration</A>
|
|
</H2>
|
|
|
|
|
|
<P>Here is an example for a very simple struct with two members and a total size
|
|
of 4 bytes:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Point
|
|
xcoord .word
|
|
ycoord .word
|
|
.endstruct
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>A union shares the total space between all its members; its size is the same
|
|
as that of the largest member. The offset of all members relative to the union
|
|
is zero.
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.union Entry
|
|
index .word
|
|
ptr .addr
|
|
.endunion
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>A struct or union may 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.</P>
|
|
<P>Storage allocators may contain a multiplier. A struct may also contain members
|
|
and definitions of local structs/unions. Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Circle
|
|
.struct Point
|
|
.word 2 ; Allocate two words
|
|
.endstruct
|
|
Radius .word
|
|
.endstruct
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In this example the size of the Circle struct is 6 (three words).</P>
|
|
|
|
|
|
<H2><A NAME="ss15.3">15.3</A> <A HREF="#toc15.3">The storage allocator keywords</A>
|
|
</H2>
|
|
|
|
|
|
<P>
|
|
<DL>
|
|
|
|
<DT><B>.BYTE, .RES</B><DD>
|
|
<P>Allocates multiples of 1 byte. <CODE>.RES</CODE> requires an operand.</P>
|
|
|
|
<DT><B>.DBYT, .WORD, .ADDR</B><DD>
|
|
<P>Allocates multiples of 2 bytes.</P>
|
|
|
|
<DT><B>.FARADDR</B><DD>
|
|
<P>Allocates multiples of 3 bytes.</P>
|
|
|
|
<DT><B>.DWORD</B><DD>
|
|
<P>Allocates multiples of 4 bytes.</P>
|
|
|
|
<DT><B>.TAG</B><DD>
|
|
<P>Allocates a previously defined struct.</P>
|
|
|
|
<DT><B>.STRUCT, .UNION</B><DD>
|
|
<P>Begins a nested .struct or .union definition, and allocates it.
|
|
Note that its member offset values will begin at 0, unless this nested
|
|
structure is anonymous, in which case they will instead become members of
|
|
the enclosing scope.</P>
|
|
|
|
</DL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss15.4">15.4</A> <A HREF="#toc15.4">The <CODE>.ORG</CODE> keyword</A>
|
|
</H2>
|
|
|
|
|
|
<P>The <CODE>.ORG</CODE> keyword changes the offset value that is assigned to subsequent
|
|
member names. It's useful when using a struct to define the names of the
|
|
registers in an I/O chip. Example:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; 6551
|
|
.struct ACIA ; Asynchronous Communications Interface Adapter
|
|
.org $031C
|
|
DATA .byte
|
|
STATUS .byte
|
|
CMD .byte ; Command register
|
|
CTRL .byte ; Control register
|
|
.endstruct
|
|
|
|
lda ACIA::DATA ; Get an RS-232 character
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss15.5">15.5</A> <A HREF="#toc15.5">The <CODE>.TAG</CODE> keyword</A>
|
|
</H2>
|
|
|
|
|
|
<P>By using the
|
|
<A HREF="#.TAG">.TAG</A> keyword, it is possible to reserve
|
|
space for an already defined struct or union within another struct:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Point
|
|
xcoord .word
|
|
ycoord .word
|
|
.endstruct
|
|
|
|
.struct Circle
|
|
Origin .tag Point
|
|
Radius .byte
|
|
.endstruct
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Actual space for a struct or union may be allocated by using the
|
|
<A HREF="#.TAG">.TAG</A> directive.
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
C: .tag Circle
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Members are just offsets from the start of the struct or union. To
|
|
access a field of a struct, the member offset must be added to the address of
|
|
the struct variable itself:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lda C + Circle::Radius ; Load circle radius
|
|
lda C + Circle::Origin + Point::ycoord ; Load circle origin.ycoord
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>Nested structures or unions are treated differently depending on whether they
|
|
are anonymous. If named, a new structure definition is created within the
|
|
enclosing scope, with its offsets beginning at 0. If anonymous, the members of
|
|
the new structure are added to the enclosing scope instead, with offsets
|
|
continuing through that scope. Example:</P>
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.struct Object
|
|
id .byte ; Object::id = 0
|
|
target .struct Point ; Object::target = 1
|
|
xcoord .word ; Object::Point::xcoord = 0
|
|
ycoord .word ; Object::Point::ycoord = 2
|
|
.endstruct
|
|
cost .struct ; Object::cost = 5
|
|
price .word ; Object::price = 5
|
|
tax .word ; Object::tax = 7
|
|
.endstruct
|
|
.struct
|
|
radius .word ; Object::radius = 9
|
|
.endstruct
|
|
.endstruct
|
|
|
|
O: .tag Object
|
|
lda O + Object::target + Object::Point::ycoord ; Named struct
|
|
lda O + Object::tax ; Anonymous
|
|
lda O + Object::radius ; Anonymous
|
|
|
|
; Be careful not to use a named nested structure without also adding the
|
|
; offset to the nested structure itself.
|
|
lda O + Object::Point::ycoord ; Incorrect!
|
|
lda O + Object::target + Object::Point::ycoord ; Correct
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
</P>
|
|
<P>In this example, the first nested structure is named "Point", and its member
|
|
offsets begin at 0. On the other hand, the two anonymous structures simply
|
|
continue to add members to the enclosing "Object" structure.</P>
|
|
<P>Note that an anonymous structure does not need a member name, since all of its
|
|
members become part of the enclosing structure. The "cost" member in the
|
|
example is redundantly the same offset as its first member "price".</P>
|
|
|
|
|
|
<H2><A NAME="ss15.6">15.6</A> <A HREF="#toc15.6">Limitations</A>
|
|
</H2>
|
|
|
|
|
|
<P>Structs and unions currently are implemented as nested symbol tables (in fact,
|
|
they were a by-product of the improved scoping rules). Currently, the
|
|
assembler has no idea of types. That means that the
|
|
<A HREF="#.TAG">.TAG</A> keyword only will allocate space. You won't be able to initialize
|
|
variables declared with
|
|
<A HREF="#.TAG">.TAG</A>; and, adding an embedded
|
|
structure to another structure with
|
|
<A HREF="#.TAG">.TAG</A> will not make
|
|
that added structure accessible by using the '::' operator.</P>
|
|
|
|
|
|
|
|
<H2><A NAME="condes"></A> <A NAME="s16">16.</A> <A HREF="#toc16">Module constructors/destructors</A></H2>
|
|
|
|
|
|
<P><EM>Note:</EM> This section applies mostly to C programs, so the explanation
|
|
below uses examples from the C libraries. However, the feature may also be
|
|
useful for assembler programs.</P>
|
|
|
|
|
|
<H2><A NAME="ss16.1">16.1</A> <A HREF="#toc16.1">Module constructors/destructors Overview</A>
|
|
</H2>
|
|
|
|
|
|
<P>Using the <CODE>
|
|
<A HREF="#.CONSTRUCTOR">.CONSTRUCTOR</A></CODE>, <CODE>
|
|
<A HREF="#.DESTRUCTOR">.DESTRUCTOR</A></CODE> and <CODE>
|
|
<A HREF="#.INTERRUPTOR">.INTERRUPTOR</A></CODE> keywords it is possible to export functions in a
|
|
special way. The linker is able to generate tables with all functions of a
|
|
specific type. Such a table will <EM>only</EM> include symbols from object
|
|
files that are linked into a specific executable. This may be used to add
|
|
initialization and cleanup code for library modules, or a table of interrupt
|
|
handler functions.</P>
|
|
<P>The C heap functions are an example where module initialization code is used.
|
|
All heap functions (<CODE>malloc</CODE>, <CODE>free</CODE>, ...) work with a few
|
|
variables that contain the start and the end of the heap, pointers to the free
|
|
list and so on. Since the end of the heap depends on the size and start of the
|
|
stack, it must be initialized at runtime. However, initializing these
|
|
variables for programs that do not use the heap are a waste of time and
|
|
memory.</P>
|
|
<P>So the central module defines a function that contains initialization code and
|
|
exports this function using the <CODE>.CONSTRUCTOR</CODE> statement. If (and only if)
|
|
this module is added to an executable by the linker, the initialization
|
|
function will be placed into the table of constructors by the linker. The C
|
|
startup code will call all constructors before <CODE>main</CODE> and all destructors
|
|
after <CODE>main</CODE>, so without any further work, the heap initialization code is
|
|
called once the module is linked in.</P>
|
|
<P>While it would be possible to add explicit calls to initialization functions
|
|
in the startup code, the new approach has several advantages:</P>
|
|
<P>
|
|
<OL>
|
|
<LI>If a module is not included, the initialization code is not linked in and not
|
|
called. So you don't pay for things you don't need.
|
|
</LI>
|
|
<LI>Adding another library that needs initialization does not mean that the
|
|
startup code has to be changed. Before we had module constructors and
|
|
destructors, the startup code for all systems had to be adjusted to call the
|
|
new initialization code.
|
|
</LI>
|
|
<LI>The feature saves memory: Each additional initialization function needs just
|
|
two bytes in the table (a pointer to the function).
|
|
</LI>
|
|
</OL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="ss16.2">16.2</A> <A HREF="#toc16.2">Calling order</A>
|
|
</H2>
|
|
|
|
|
|
<P>The symbols are sorted in increasing priority order by the linker when using
|
|
one of the builtin linker configurations, so the functions with lower
|
|
priorities come first and are followed by those with higher priorities. The C
|
|
library runtime subroutine that walks over the function tables calls the
|
|
functions starting from the top of the table - which means that functions with
|
|
a high priority are called first.</P>
|
|
<P>So when using the C runtime, functions are called with high priority functions
|
|
first, followed by low priority functions.</P>
|
|
|
|
|
|
<H2><A NAME="ss16.3">16.3</A> <A HREF="#toc16.3">Pitfalls</A>
|
|
</H2>
|
|
|
|
|
|
<P>When using these special symbols, please take care of the following:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>The linker will only generate function tables, it will not generate code to
|
|
call these functions. If you're using the feature in some other than the
|
|
existing C environments, you have to write code to call all functions in a
|
|
linker generated table yourself. See the <CODE>condes</CODE> and <CODE>callirq</CODE> modules
|
|
in the C runtime for an example on how to do this.
|
|
</LI>
|
|
<LI>The linker will only add addresses of functions that are in modules linked to
|
|
the executable. This means that you have to be careful where to place the
|
|
condes functions. If initialization or an irq handler is needed for a group of
|
|
functions, be sure to place the function into a module that is linked in
|
|
regardless of which function is called by the user.
|
|
</LI>
|
|
<LI>The linker will generate the tables only when requested to do so by the
|
|
<CODE>FEATURE CONDES</CODE> statement in the linker config file. Each table has to
|
|
be requested separately.
|
|
</LI>
|
|
<LI>Constructors and destructors may have priorities. These priorities determine
|
|
the order of the functions in the table. If your initialization or cleanup code
|
|
does depend on other initialization or cleanup code, you have to choose the
|
|
priority for the functions accordingly.
|
|
</LI>
|
|
<LI>Besides the <CODE>
|
|
<A HREF="#.CONSTRUCTOR">.CONSTRUCTOR</A></CODE>, <CODE>
|
|
<A HREF="#.DESTRUCTOR">.DESTRUCTOR</A></CODE> and <CODE>
|
|
<A HREF="#.INTERRUPTOR">.INTERRUPTOR</A></CODE> statements, there is also a more generic command:
|
|
<CODE>
|
|
<A HREF="#.CONDES">.CONDES</A></CODE>. This allows to specify an
|
|
additional type. Predefined types are 0 (constructor), 1 (destructor) and 2
|
|
(interruptor). The linker generates a separate table for each type on request.
|
|
</LI>
|
|
</UL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="s17">17.</A> <A HREF="#toc17">Porting sources from other assemblers</A></H2>
|
|
|
|
|
|
<P>Sometimes it is necessary to port code written for older assemblers to ca65.
|
|
In some cases, this can be done without any changes to the source code by
|
|
using the emulation features of ca65 (see <CODE>
|
|
<A HREF="#.FEATURE">.FEATURE</A></CODE>). In other cases, it is necessary to make changes to the
|
|
source code.</P>
|
|
<P>Probably the biggest difference is the handling of the <CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> directive. ca65 generates relocatable code, and placement is
|
|
done by the linker. Most other assemblers generate absolute code, placement is
|
|
done within the assembler and there is no external linker.</P>
|
|
<P>In general it is not a good idea to write new code using the emulation
|
|
features of the assembler, but there may be situations where even this rule is
|
|
not valid.</P>
|
|
|
|
<H2><A NAME="ss17.1">17.1</A> <A HREF="#toc17.1">TASS</A>
|
|
</H2>
|
|
|
|
|
|
<P>You need to use some of the ca65 emulation features to simulate the behaviour
|
|
of such simple assemblers.</P>
|
|
<P>
|
|
<OL>
|
|
<LI>Prepare your sourcecode like this:
|
|
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; if you want TASS style labels without colons
|
|
.feature labels_without_colons
|
|
|
|
; if you want TASS style character constants
|
|
; ("a" instead of the default 'a')
|
|
.feature loose_char_term
|
|
|
|
.word *+2 ; the cbm load address
|
|
|
|
[yourcode here]
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
|
|
notice that the two emulation features are mostly useful for porting
|
|
sources originally written in/for TASS, they are not needed for the
|
|
actual "simple assembler operation" and are not recommended if you are
|
|
writing new code from scratch.
|
|
</LI>
|
|
<LI>Replace all program counter assignments (which are not possible in ca65
|
|
by default, and the respective emulation feature works different from what
|
|
you'd expect) by another way to skip to memory locations, for example the
|
|
<CODE>
|
|
<A HREF="#.RES">.RES</A></CODE> directive.
|
|
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
; *=$2000
|
|
.res $2000-* ; reserve memory up to $2000
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
|
|
Please note that other than the original TASS, ca65 can never move the program
|
|
counter backwards - think of it as if you are assembling to disk with TASS.
|
|
</LI>
|
|
<LI>Conditional assembly (<CODE>.ifeq</CODE>/<CODE>.endif</CODE>/<CODE>.goto</CODE> etc.) must be
|
|
rewritten to match ca65 syntax. Most importantly notice that due to the lack
|
|
of <CODE>.goto</CODE>, everything involving loops must be replaced by
|
|
<CODE>
|
|
<A HREF="#.REPEAT">.REPEAT</A></CODE>.
|
|
</LI>
|
|
<LI>To assemble code to a different address than it is executed at, use the
|
|
<CODE>
|
|
<A HREF="#.ORG">.ORG</A></CODE> directive instead of
|
|
<CODE>.offs</CODE>-constructs.
|
|
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
.org $1800
|
|
|
|
[floppy code here]
|
|
|
|
.reloc ; back to normal
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
</LI>
|
|
<LI>Then assemble like this:
|
|
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
cl65 --start-addr 0x0ffe -t none myprog.s -o myprog.prg
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
|
|
Note that you need to use the actual start address minus two, since two bytes
|
|
are used for the cbm load address.
|
|
</LI>
|
|
</OL>
|
|
</P>
|
|
|
|
|
|
<H2><A NAME="s18">18.</A> <A HREF="#toc18">Copyright</A></H2>
|
|
|
|
|
|
<P>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:</P>
|
|
<P>This software is provided 'as-is', without any expressed or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.</P>
|
|
<P>Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:</P>
|
|
<P>
|
|
<OL>
|
|
<LI> The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.</LI>
|
|
<LI> Altered source versions must be plainly marked as such, and must not
|
|
be misrepresented as being the original software.</LI>
|
|
<LI> This notice may not be removed or altered from any source
|
|
distribution.</LI>
|
|
</OL>
|
|
</P>
|
|
|
|
|
|
|
|
</BODY>
|
|
</HTML>
|