From b6ded8501f38d195ac3782e0d602543b923ad502 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 21 Feb 2021 01:24:44 +0100 Subject: [PATCH] added 'align_word' and 'align_page' block options to control block start address alignment in the assembler --- .../compiler/astprocessing/AstChecker.kt | 2 +- .../compiler/target/c64/codegen/AsmGen.kt | 9 +++++++-- docs/source/syntaxreference.rst | 11 +++++----- docs/source/todo.rst | 2 +- examples/test.p8 | 20 +++++++++++++++++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index b509aee6c..01aab09a7 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -752,7 +752,7 @@ internal class AstChecker(private val program: Program, err("this directive may only occur in a block or at module level") if(directive.args.isEmpty()) err("missing option directive argument(s)") - else if(directive.args.map{it.name in setOf("enable_floats", "force_output", "no_sysinit")}.any { !it }) + else if(directive.args.map{it.name in setOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page")}.any { !it }) err("invalid option directive argument(s)") } "%target" -> { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 99c3e0d31..de6316718 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -181,8 +181,13 @@ internal class AsmGen(private val program: Program, out("\n\n; ---- block: '${block.name}' ----") if(block.address!=null) out("* = ${block.address!!.toHex()}") - else - out("\t.align 2") + else { + if("align_word" in block.options()) + out("\t.align 2") + else if("align_page" in block.options()) + out("\t.align $100") + } + out("${block.name}\t" + (if("force_output" in block.options()) ".block\n" else ".proc\n")) outputSourceLine(block) diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 02f883ac0..d25bfea20 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -120,17 +120,18 @@ Directives Level: module, block. Sets special compiler options. - - For a module option, there is ``enable_floats``, which will tell the compiler + - ``enable_floats`` (module level) tells the compiler to deal with floating point numbers (by using various subroutines from the Commodore-64 kernal). Otherwise, floating point support is not enabled. Normally you don't have to use this yourself as importing the ``floats`` library is required anyway and that will enable it for you automatically. - - There's also ``no_sysinit`` which cause the resulting program to *not* include + - ``no_sysinit`` (module level) which cause the resulting program to *not* include the system re-initialization logic of clearing the screen, resetting I/O config etc. You'll have to take care of that yourself. The program will just start running from whatever state the machine is in when the program was launched. - - When used in a block with the ``force_output`` option, it will force the block to be outputted - in the final program. Can be useful to make sure some - data is generated that would otherwise be discarded because it's not referenced (such as sprite data). + - ``force_output`` (in a block) will force the block to be outputted in the final program. + Can be useful to make sure some data is generated that would otherwise be discarded because it's not referenced (such as sprite data). + - ``align_word`` (in a block) will make the assembler align the start address of this block on a word boundary in memory (so, an even memory address). + - ``align_page`` (in a block) will make the assembler align the start address of this block on a page boundary in memory (so, the LSB of the address is 0). .. data:: %asmbinary "" [, [, ]] diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bbe6db484..a71c000a0 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -16,7 +16,7 @@ TODO - refactor the compiler optimizers into their own submodule? - optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation - add a compiler option to not remove unused subroutines. this allows for building library programs -- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as 'v_' +- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_`` - option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging) - c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking) - some support for recursive subroutines? diff --git a/examples/test.p8 b/examples/test.p8 index e0d0080cf..060185a4c 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,9 +4,13 @@ main { +; $1F9C0 - $1F9FF PSG registers + sub start() { uword xx = &b2.zz xx=&b3.zz + xx=&b4.zz + xx=&b5.zz txt.print_uwhex(&main, true) txt.nl() @@ -14,6 +18,10 @@ main { txt.nl() txt.print_uwhex(&b3, true) txt.nl() + txt.print_uwhex(&b4, true) + txt.nl() + txt.print_uwhex(&b5, true) + txt.nl() } } @@ -24,3 +32,15 @@ b2 { b3 $4001 { str zz="bye" } + +b4 { + %option align_word + + str zz="wut" +} + +b5 { + %option align_page + + str zz="wut2" +}