API change: added alignment parameter to memory() function

This commit is contained in:
Irmen de Jong
2022-01-24 18:58:57 +01:00
parent 118196a0bf
commit b7d06f2c0a
10 changed files with 37 additions and 38 deletions

View File

@@ -56,7 +56,7 @@ class AsmGen(private val program: Program,
private val assignmentAsmGen = AssignmentAsmGen(program, this) private val assignmentAsmGen = AssignmentAsmGen(program, this)
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
internal val loopEndLabels = ArrayDeque<String>() internal val loopEndLabels = ArrayDeque<String>()
internal val slabs = mutableMapOf<String, UInt>() internal val slabs = mutableMapOf<String, Pair<UInt, UInt>>()
internal val removals = mutableListOf<Pair<Statement, IStatementContainer>>() internal val removals = mutableListOf<Pair<Statement, IStatementContainer>>()
private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance<Assignment>() } private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance<Assignment>() }
@@ -245,8 +245,11 @@ class AsmGen(private val program: Program,
private fun slaballocations() { private fun slaballocations() {
out("; memory slabs") out("; memory slabs")
out("prog8_slabs\t.block") out("prog8_slabs\t.block")
for((name, size) in slabs) for((name, info) in slabs) {
out("$name\t.fill $size") if(info.second>1u)
out("\t.align ${info.second.toHex()}")
out("$name\t.fill ${info.first}")
}
out("\t.bend") out("\t.bend")
} }

View File

@@ -453,10 +453,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value
require(name.all { it.isLetterOrDigit() || it=='_' }) {"memory name should be a valid symbol name"} require(name.all { it.isLetterOrDigit() || it=='_' }) {"memory name should be a valid symbol name"}
val size = (fcall.args[1] as NumericLiteralValue).number.toUInt() val size = (fcall.args[1] as NumericLiteralValue).number.toUInt()
val align = (fcall.args[2] as NumericLiteralValue).number.toUInt()
val existingSize = asmgen.slabs[name] val existing = asmgen.slabs[name]
if(existingSize!=null && existingSize!=size) if(existing!=null && (existing.first!=size || existing.second!=size))
throw AssemblyError("memory slab '$name' already exists with a different size ($size) at ${fcall.position}") 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) val slabname = IdentifierReference(listOf("prog8_slabs", name), fcall.position)
slabname.linkParents(fcall) 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) AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, null, program, asmgen)
val assign = AsmAssignment(src, target, false, program.memsizer, fcall.position) val assign = AsmAssignment(src, target, false, program.memsizer, fcall.position)
asmgen.translateNormalAssignment(assign) 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?) { private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) {

View File

@@ -76,7 +76,7 @@ io_error:
sub list_files(ubyte drivenumber, uword pattern_ptr, uword name_ptrs, ubyte max_names) -> ubyte { 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. ; -- 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 uword buffer_start = names_buffer
ubyte files_found = 0 ubyte files_found = 0
if lf_start_list(drivenumber, pattern_ptr) { if lf_start_list(drivenumber, pattern_ptr) {

View File

@@ -228,9 +228,19 @@ class TestMemory: FunSpec({
compileText(C64Target, false, """ compileText(C64Target, false, """
main { main {
sub start() { sub start() {
uword @shared mem = memory("a b c", 100) uword @shared mem = memory("a b c", 100, $100)
} }
} }
""", writeAssembly = true).assertSuccess() """, writeAssembly = true).assertSuccess()
} }
test("memory() with invalid argument") {
compileText(C64Target, false, """
main {
sub start() {
uword @shared mem1 = memory("abc", 100, -2)
}
}
""", writeAssembly = true).assertFailure()
}
}) })

View File

@@ -154,7 +154,7 @@ private val functionSignatures: List<FSignature> = listOf(
FSignature("rnd" , false, emptyList(), DataType.UBYTE), FSignature("rnd" , false, emptyList(), DataType.UBYTE),
FSignature("rndw" , false, emptyList(), DataType.UWORD), FSignature("rndw" , false, emptyList(), DataType.UWORD),
FSignature("rndf" , false, emptyList(), DataType.FLOAT), 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("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("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), FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),

View File

@@ -979,9 +979,12 @@ sizeof(name)
swap(x, y) swap(x, y)
Swap the values of numerical variables (or memory locations) x and y in a fast way. 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, 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. 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, When reusing blocks in that way, it is required that the size argument is the same,
otherwise you'll get a compilation error. otherwise you'll get a compilation error.

View File

@@ -3,6 +3,8 @@ TODO
For next release 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 Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
- nameInAssemblyCode() should search smarter - 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) - 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. - 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 - Fix: don't report as recursion if code assigns address of its own subroutine to something, rather than calling it

View File

@@ -8,8 +8,8 @@
main { main {
const ubyte database_size = 100 const ubyte database_size = 100
uword animal_names_buf = memory("animalnames", 500) uword animal_names_buf = memory("animalnames", 500, 0)
uword questions_buf = memory("questions", 2000) uword questions_buf = memory("questions", 2000, 0)
uword animal_names_ptr uword animal_names_ptr
uword questions_ptr uword questions_ptr

View File

@@ -18,12 +18,9 @@ main {
} }
sub demo1() { sub demo1() {
uword pixels = memory("pixels", 320)
uword yy = 10 uword yy = 10
uword xx uword xx
uword pp
uword cnt uword cnt
pp=pixels
gfx2.monochrome_stipple(true) gfx2.monochrome_stipple(true)
gfx2.disc(320,240,200,1) gfx2.disc(320,240,200,1)
@@ -34,11 +31,6 @@ main {
gfx2.vertical_line(xx, 0, 480, 0) gfx2.vertical_line(xx, 0, 480, 0)
} }
for cnt in 0 to 319 {
@(pp) = 255
pp++
}
xx=gfx2.width/2 xx=gfx2.width/2
yy=10 yy=10
gfx2.monochrome_stipple(false) gfx2.monochrome_stipple(false)

View File

@@ -4,20 +4,11 @@
main { main {
sub start() { sub start() {
word ww = calculate(6) uword m1 = memory("mem1", 123, $100)
txt.print_w(ww) uword m2 = memory("mem2", 999, 2)
txt.print_uwhex(m1, true)
txt.nl() txt.nl()
ubyte bb = calculate2(6) txt.print_uwhex(m2, true)
txt.print_ub(bb)
txt.nl() txt.nl()
} }
sub calculate2(ubyte row) -> ubyte {
return 8+row
}
sub calculate(ubyte row) -> word {
return 8+row
}
} }