mirror of
https://github.com/irmen/prog8.git
synced 2025-08-07 21:25:18 +00:00
API change: added alignment parameter to memory() function
This commit is contained in:
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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?) {
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@@ -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),
|
||||||
|
@@ -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.
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user