diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 0475c42fb..7123940b2 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -915,6 +915,17 @@ internal class AstChecker(private val program: Program, errors.err(msg, directive.position) } when(directive.directive) { + "%align" -> { + if(directive.parent !is INameScope || directive.parent is Module) + err("this directive can't be used here") + if(directive.args.size!=1 || directive.args[0].int == null) + err("missing correct alignment size") + if(directive.args[0].int!! >= 64u) + errors.info("large alignment might waste a lot of memory (check Gaps in assembler output)", directive.position) + val prev = directive.previousSibling() + if (prev !=null && prev !is Block && prev !is Break && prev !is Continue && prev !is Jump && prev !is Return && prev !is Subroutine && prev !is VarDecl) + errors.warn("dangerous location for %align, after a regular statement it will likely corrupt the program", directive.position) + } "%output" -> { if(directive.parent !is Module) err("this directive may only occur at module level") @@ -1009,14 +1020,6 @@ internal class AstChecker(private val program: Program, if(directive.args.size!=1 || directive.args[0].name !in allowedEncodings) err("invalid encoding directive, expected one of $allowedEncodings") } - "%align" -> { - if(directive.parent !is INameScope || directive.parent is Module) - err("this directive can't be used here") - if(directive.args.size!=1 || directive.args[0].int == null) - err("missing correct alignment size") - if(directive.args[0].int!! >= 64u) - errors.info("large alignment might waste a lot of memory (check Gaps in assembler output)", directive.position) - } else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position) } super.visit(directive) diff --git a/docs/source/programming.rst b/docs/source/programming.rst index d576f0ddf..c1a4c1d5e 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -28,7 +28,7 @@ Comments Directive These are special instructions for the compiler, to change how it processes the code and what kind of program it creates. A directive is on its own line in the file, and - starts with ``%``, optionally followed by some arguments. + starts with ``%``, optionally followed by some arguments. See the syntax reference for all directives. Code block A block of actual program code. It has a starting address in memory, @@ -202,7 +202,7 @@ Values will usually be part of an expression or assignment statement:: byte counter = 42 ; variable of size 8 bits, with initial value 42 -*putting a variable in zeropage:* +**putting a variable in zeropage:** If you add the ``@zp`` tag to the variable declaration, the compiler will prioritize this variable when selecting variables to put into zeropage (but no guarantees). If there are enough free locations in the zeropage, it will try to fill it with as much other variables as possible (before they will be put in regular memory pages). @@ -217,7 +217,7 @@ Example:: uword @requirezp zppointer = $4000 -*shared tag:* +**shared variables:** If you add the ``@shared`` tag to the variable declaration, the compiler will know that this variable is a prog8 variable shared with some assembly code elsewhere. This means that the assembly code can refer to the variable even if it's otherwise not used in prog8 code itself. @@ -227,6 +227,18 @@ when assembling the rest of the code). Example:: byte @shared assemblyVariable = 42 +**memory alignment:** +A string or array variable can be aligned to a couple of possible interval sizes in memory. +The use for this is very situational, but two examples are: sprite data for the C64 that needs +to be on a 64 byte aligned memory address, or an array aligned on a full page boundary to avoid +any possible extra page boundary clock cycles on certain instructions when accessing the array. +You can align on word, 64 bytes, and page boundaries:: + + ubyte[] @alignword array = [1, 2, 3, 4, ...] + ubyte[] @align64 spritedata = [ %00000000, %11111111, ...] + ubyte[] @alignpage lookup = [11, 22, 33, 44, ...] + + Integers ^^^^^^^^ diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index e9c8c5add..a7dd579dd 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -40,73 +40,6 @@ Examples:: Directives ----------- -.. data:: %output - - Level: module. - Global setting, selects program output type. Default is ``prg``. - - - type ``raw`` : no header at all, just the raw machine code data - - type ``prg`` : C64 program (with load address header) - - -.. 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:: %zeropage