.. _syntaxreference:
================
Syntax Reference
================
Module file
-----------
This is a file with the ``.p8`` suffix, containing *directives* and *code blocks*, described below.
The file is a text file, saved in UTF-8 encoding, which can also contain:
Lines, whitespace, indentation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Line endings are significant because *only one* declaration, statement or other instruction can occur on every line.
Other whitespace and line indentation is arbitrary and ignored by the compiler.
You can use tabs or spaces as you wish.
Source code comments
^^^^^^^^^^^^^^^^^^^^
Everything on a line after a semicolon ``;`` is a comment and is ignored.
If the whole line is just a comment, it will be copied into the resulting assembly source code.
This makes it easier to understand and relate the generated code.
Everything surrounded with ``/*`` and ``*/``, this can span multiple lines, is a block-comment and is ignored.
This block comment is experimental for now: it may change or even be removed again in a future compiler version.
Examples::
counter = 42 ; set the initial value to 42
; next is the code that...
/* this
is
all
ignored */
.. _directives:
Directives
-----------
.. data:: %address
Level: module.
Global setting, set the program's start memory address. It's usually fixed at ``$0801`` because the
default launcher type is a CBM-BASIC program. But you have to specify this address yourself when
you don't use a CBM-BASIC launcher.
.. data:: %align
Level: not at module scope.
Tells the assembler to continue assembling on the given alignment interval. For example, ``%align $100``
will insert an assembler command to align on the next page boundary.
Note that this has no impact on variables following this directive! Prog8 reallocates all variables
using different rules. If you want to align a specific variable (array or string), you should use
one of the alignment tags for variable declarations instead.
Valid intervals are from 2 to 65536.
**Warning:** if you use this directive in between normal statements, it will disrupt the output
of the machine code instructions by making gaps between them, this will probably crash the program!
.. data:: %asm {{ ... }}
Level: not at module scope.
Declares that a piece of *assembly code* is inside the curly braces.
This code will be copied as-is into the generated output assembly source file.
Note that the start and end markers are both *double curly braces* to minimize the chance
that the assembly code itself contains either of those. If it does contain a ``}}``,
it will confuse the parser.
If you use the correct scoping rules you can access symbols from the prog8 program from inside
the assembly code. Sometimes you'll have to declare a variable in prog8 with `@shared` if it
is only used in such assembly code.
.. note::
64tass syntax is required for the assembly code. As such, mnemonics need to be written in lowercase.
.. caution::
Avoid using single-letter symbols in included assembly code, as they could be confused with CPU registers.
Also, note that all prog8 symbols are prefixed in assembly code, see :ref:`symbol-prefixing`.
.. data:: %asmbinary "" [, [, ]]
Level: not at module scope.
This directive can only be used inside a block.
The assembler itself will include the file as binary bytes at this point, prog8 will not process this at all.
This means that the filename must be spelled exactly as it appears on your computer's file system.
Note that this filename may differ in case compared to when you chose to load the file from disk from within the
program code itself (for example on the C64 and X16 there's the PETSCII encoding difference).
The file is located relative to the current working directory!
The optional offset and length can be used to select a particular piece of the file.
To reference the contents of the included binary data, you can put a label in your prog8 code
just before the %asmbinary. To find out where the included binary data ends, add another label directly after it.
An example program for this can be found below at the description of %asminclude.
.. data:: %asminclude ""
Level: not at module scope.
This directive can only be used inside a block.
The assembler will include the file as raw assembly source text at this point,
prog8 will not process this at all. Symbols defined in the included assembly can not be referenced
from prog8 code. However they can be referenced from other assembly code if properly prefixed.
You can of course use a label in your prog8 code just before the %asminclude directive, and reference
that particular label to get to (the start of) the included assembly.
Be careful: you risk symbol redefinitions or duplications if you include a piece of
assembly into a prog8 block that already defines symbols itself.
The compiler first looks for the file relative to the same directory as the module containing this statement is in,
if the file can't be found there it is searched relative to the current directory.
.. caution::
Avoid using single-letter symbols in included assembly code, as they could be confused with CPU registers.
Also, note that all prog8 symbols are prefixed in assembly code, see :ref:`symbol-prefixing`.
Here is a small example program to show how to use labels to reference the included contents from prog8 code::
%import textio
%zeropage basicsafe
main {
sub start() {
txt.print("first three bytes of included asm:\n")
uword included_addr = &included_asm
txt.print_ub(@(included_addr))
txt.spc()
txt.print_ub(@(included_addr+1))
txt.spc()
txt.print_ub(@(included_addr+2))
txt.print("\nfirst three bytes of included binary:\n")
included_addr = &included_bin
txt.print_ub(@(included_addr))
txt.spc()
txt.print_ub(@(included_addr+1))
txt.spc()
txt.print_ub(@(included_addr+2))
txt.nl()
return
included_asm:
%asminclude "inc.asm"
included_bin:
%asmbinary "inc.bin"
end_of_included_bin:
}
}
.. data:: %breakpoint
Level: not at module scope.
Defines a debugging breakpoint at this location. See :ref:`debugging`
.. data:: %encoding
Overrides, in the module file it occurs in,
the default text encoding to use for strings and characters that have no explicit encoding prefix.
You can use one of the recognised encoding names, see :ref:`encodings`.
.. data:: %import
Level: module.
This reads and compiles the named module source file as part of your current program.
Symbols from the imported module become available in your code,
without a module or filename prefix.
You can import modules one at a time, and importing a module more than once has no effect.
.. data:: %launcher
Level: module.
Global setting, selects the program launcher stub to use.
Only relevant when using the ``prg`` output type. Defaults to ``basic``.
- type ``basic`` : add a tiny C64 BASIC program, with a SYS statement calling into the machine code
- type ``none`` : no launcher logic is added at all
.. data:: %memtop
Level: module.
Global setting, changes the program's top memory address. This is usually specified internally by the compiler target,
but with this you can change it to another value. This can be useful for example to 'reserve' a piece
of memory at the end of program space where other data such as external library files can be loaded into.
This memtop value is used for a check instruction for the assembler to see if the resulting program size
exceeds the given memtop address. This value is exclusive, so $a000 means that $a000 is the first address
that program can no longer use. Everything up to and including $9fff is still usable.
.. data:: %option