From b7d06f2c0ac8bfc5c585819d42411e45b00de737 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 24 Jan 2022 18:58:57 +0100 Subject: [PATCH] API change: added alignment parameter to memory() function --- .../codegen/target/cpu6502/codegen/AsmGen.kt | 9 ++++++--- .../cpu6502/codegen/BuiltinFunctionsAsmGen.kt | 9 +++++---- compiler/res/prog8lib/diskio.p8 | 2 +- compiler/test/TestMemory.kt | 12 +++++++++++- .../prog8/compilerinterface/BuiltinFunctions.kt | 2 +- docs/source/programming.rst | 7 +++++-- docs/source/todo.rst | 5 ++--- examples/animals.p8 | 4 ++-- examples/cx16/testgfx2.p8 | 8 -------- examples/test.p8 | 17 ++++------------- 10 files changed, 37 insertions(+), 38 deletions(-) diff --git a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt index 3265ef6a7..cb899ea7f 100644 --- a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt @@ -56,7 +56,7 @@ class AsmGen(private val program: Program, private val assignmentAsmGen = AssignmentAsmGen(program, this) private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) internal val loopEndLabels = ArrayDeque() - internal val slabs = mutableMapOf() + internal val slabs = mutableMapOf>() internal val removals = mutableListOf>() private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance() } @@ -245,8 +245,11 @@ class AsmGen(private val program: Program, private fun slaballocations() { out("; memory slabs") out("prog8_slabs\t.block") - for((name, size) in slabs) - out("$name\t.fill $size") + for((name, info) in slabs) { + if(info.second>1u) + out("\t.align ${info.second.toHex()}") + out("$name\t.fill ${info.first}") + } out("\t.bend") } diff --git a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index dd3b1d63c..61f8750f0 100644 --- a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -453,10 +453,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value require(name.all { it.isLetterOrDigit() || it=='_' }) {"memory name should be a valid symbol name"} val size = (fcall.args[1] as NumericLiteralValue).number.toUInt() + val align = (fcall.args[2] as NumericLiteralValue).number.toUInt() - val existingSize = asmgen.slabs[name] - if(existingSize!=null && existingSize!=size) - throw AssemblyError("memory slab '$name' already exists with a different size ($size) at ${fcall.position}") + val existing = asmgen.slabs[name] + if(existing!=null && (existing.first!=size || existing.second!=size)) + throw AssemblyError("memory slab '$name' already exists with a different size or alignment at ${fcall.position}") val slabname = IdentifierReference(listOf("prog8_slabs", name), fcall.position) slabname.linkParents(fcall) @@ -468,7 +469,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, null, program, asmgen) val assign = AsmAssignment(src, target, false, program.memsizer, fcall.position) asmgen.translateNormalAssignment(assign) - asmgen.slabs[name] = size + asmgen.slabs[name] = Pair(size, align) } private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) { diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index 92433b7b6..1d5730473 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -76,7 +76,7 @@ io_error: sub list_files(ubyte drivenumber, uword pattern_ptr, uword name_ptrs, ubyte max_names) -> ubyte { ; -- fill the array 'name_ptrs' with (pointers to) the names of the files requested. - uword names_buffer = memory("filenames", 512) + uword names_buffer = memory("filenames", 512, 0) uword buffer_start = names_buffer ubyte files_found = 0 if lf_start_list(drivenumber, pattern_ptr) { diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index 2a8a2df2a..87a253768 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -228,9 +228,19 @@ class TestMemory: FunSpec({ compileText(C64Target, false, """ main { sub start() { - uword @shared mem = memory("a b c", 100) + uword @shared mem = memory("a b c", 100, $100) } } """, writeAssembly = true).assertSuccess() } + + test("memory() with invalid argument") { + compileText(C64Target, false, """ + main { + sub start() { + uword @shared mem1 = memory("abc", 100, -2) + } + } + """, writeAssembly = true).assertFailure() + } }) diff --git a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt index 035f2f34e..34994e1aa 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt @@ -154,7 +154,7 @@ private val functionSignatures: List = listOf( FSignature("rnd" , false, emptyList(), DataType.UBYTE), FSignature("rndw" , false, emptyList(), DataType.UWORD), FSignature("rndf" , false, emptyList(), DataType.FLOAT), - FSignature("memory" , true, listOf(FParam("name", arrayOf(DataType.STR)), FParam("size", arrayOf(DataType.UWORD))), DataType.UWORD), + FSignature("memory" , true, listOf(FParam("name", arrayOf(DataType.STR)), FParam("size", arrayOf(DataType.UWORD)), FParam("alignment", arrayOf(DataType.UWORD))), DataType.UWORD), FSignature("swap" , false, listOf(FParam("first", NumericDatatypes), FParam("second", NumericDatatypes)), null), FSignature("callfar" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null), FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null), diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 4d5f1abd4..46413d9a4 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -979,9 +979,12 @@ sizeof(name) swap(x, y) Swap the values of numerical variables (or memory locations) x and y in a fast way. -memory(name, size) +memory(name, size, alignment) Returns the address of the first location of a statically "reserved" block of memory of the given size in bytes, - with the given name. Requesting the address of such a named memory block again later with + with the given name. If you specify an alignment value >1, it means the block of memory will + be aligned to such a dividable address in memory, for instance an alignment of $100 means the + memory block is aligned on a page boundary, and $2 means word aligned (even addresses). + Requesting the address of such a named memory block again later with the same name, will result in the same address as before. When reusing blocks in that way, it is required that the size argument is the same, otherwise you'll get a compilation error. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e68578ac5..e2e8b067f 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ +- string.find should return index of found character + carry set if found, carry clear if not found. (fix cx16assem, it uses current behavior. Also fix docs!) +- if char in "string" should fall back to string.find if string is longer than... 16? ... @@ -22,9 +24,6 @@ Blocked by an official Commander-x16 r39 release Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ - nameInAssemblyCode() should search smarter -- string.find should return index of found character + carry set if found, carry clear if not found. (fix cx16assem, it uses current behavior. Also fix docs!) -- if char in "string" should fall back to string.find if string is longer than... 16? -- add option to memory() to get aligned memory block (word, page aligned) - Typecastexpression.isSimple: make it 'expression.isSimple' rather than always false. (this breaks some things atm) - IdentifierReference: fix equality to also include position. CallGraph can then also only store IdentifierRef instead of pair(ident, position) as keys. - Fix: don't report as recursion if code assigns address of its own subroutine to something, rather than calling it diff --git a/examples/animals.p8 b/examples/animals.p8 index 0e72c7926..3c0016b94 100644 --- a/examples/animals.p8 +++ b/examples/animals.p8 @@ -8,8 +8,8 @@ main { const ubyte database_size = 100 - uword animal_names_buf = memory("animalnames", 500) - uword questions_buf = memory("questions", 2000) + uword animal_names_buf = memory("animalnames", 500, 0) + uword questions_buf = memory("questions", 2000, 0) uword animal_names_ptr uword questions_ptr diff --git a/examples/cx16/testgfx2.p8 b/examples/cx16/testgfx2.p8 index 6317aaa76..85c9b788e 100644 --- a/examples/cx16/testgfx2.p8 +++ b/examples/cx16/testgfx2.p8 @@ -18,12 +18,9 @@ main { } sub demo1() { - uword pixels = memory("pixels", 320) uword yy = 10 uword xx - uword pp uword cnt - pp=pixels gfx2.monochrome_stipple(true) gfx2.disc(320,240,200,1) @@ -34,11 +31,6 @@ main { gfx2.vertical_line(xx, 0, 480, 0) } - for cnt in 0 to 319 { - @(pp) = 255 - pp++ - } - xx=gfx2.width/2 yy=10 gfx2.monochrome_stipple(false) diff --git a/examples/test.p8 b/examples/test.p8 index fe89488da..f0f3b9a20 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,20 +4,11 @@ main { sub start() { - word ww = calculate(6) - txt.print_w(ww) + uword m1 = memory("mem1", 123, $100) + uword m2 = memory("mem2", 999, 2) + txt.print_uwhex(m1, true) txt.nl() - ubyte bb = calculate2(6) - txt.print_ub(bb) + txt.print_uwhex(m2, true) txt.nl() } - - sub calculate2(ubyte row) -> ubyte { - return 8+row - } - - - sub calculate(ubyte row) -> word { - return 8+row - } }