From 7459896155db33c71b83f3d7a22623bfdb55d2ea Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 27 Jan 2019 22:59:40 +0100 Subject: [PATCH] finalized zeropage variable allocation --- compiler/src/prog8/ast/AstChecker.kt | 6 +- compiler/src/prog8/ast/AstRecursionChecker.kt | 2 +- compiler/src/prog8/ast/StmtReorderer.kt | 2 + compiler/src/prog8/compiler/Zeropage.kt | 35 ++---- .../intermediate/IntermediateProgram.kt | 5 +- .../src/prog8/compiler/target/c64/AsmGen.kt | 59 ++++++++-- .../prog8/compiler/target/c64/Commodore64.kt | 4 - .../src/prog8/functions/BuiltinFunctions.kt | 2 +- compiler/src/prog8/parser/ModuleParsing.kt | 1 - compiler/test/UnitTests.kt | 65 +++++----- compiler/test/ValueOperationsTests.kt | 1 - docs/source/todo.rst | 9 +- examples/rasterbars.p8 | 1 + examples/sprites.p8 | 4 +- examples/test.p8 | 111 ++++-------------- examples/wizzine.p8 | 6 +- 16 files changed, 125 insertions(+), 188 deletions(-) diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 87269454e..ade589662 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -41,14 +41,14 @@ fun printWarning(msg: String, position: Position, detailInfo: String?=null) { if(detailInfo==null) print("\n") else - println(": $detailInfo") + println(": $detailInfo\n") print("\u001b[0m") // normal } fun printWarning(msg: String) { print("\u001b[93m") // bright yellow print("Warning: $msg") - print("\u001b[0m") // normal + print("\u001b[0m\n") // normal } private class AstChecker(private val namespace: INameScope, @@ -784,7 +784,7 @@ private class AstChecker(private val namespace: INameScope, if(target is BuiltinFunctionStatementPlaceholder) { // it's a call to a builtin function. - val func = BuiltinFunctions[target.name]!! + val func = BuiltinFunctions.getValue(target.name) if(args.size!=func.parameters.size) checkResult.add(SyntaxError("invalid number of arguments", position)) else { diff --git a/compiler/src/prog8/ast/AstRecursionChecker.kt b/compiler/src/prog8/ast/AstRecursionChecker.kt index c839f9566..94a795e78 100644 --- a/compiler/src/prog8/ast/AstRecursionChecker.kt +++ b/compiler/src/prog8/ast/AstRecursionChecker.kt @@ -32,7 +32,7 @@ private class DirectedGraph { println("#vertices: $numVertices") graph.forEach { from, to -> println("$from CALLS:") - to.forEach { it -> println(" $it") } + to.forEach { println(" $it") } } val cycle = checkForCycle() if(cycle.isNotEmpty()) { diff --git a/compiler/src/prog8/ast/StmtReorderer.kt b/compiler/src/prog8/ast/StmtReorderer.kt index 753ddea88..8c6dd30fb 100644 --- a/compiler/src/prog8/ast/StmtReorderer.kt +++ b/compiler/src/prog8/ast/StmtReorderer.kt @@ -46,6 +46,8 @@ private class StatementReorderer(private val namespace: INameScope, private val module.statements.removeAll(directives) module.statements.addAll(0, directives) + // TODO make sure user-defined blocks come BEFORE library blocks + sortConstantAssignments(module.statements) } diff --git a/compiler/src/prog8/compiler/Zeropage.kt b/compiler/src/prog8/compiler/Zeropage.kt index 9121929a5..a477fbafa 100644 --- a/compiler/src/prog8/compiler/Zeropage.kt +++ b/compiler/src/prog8/compiler/Zeropage.kt @@ -11,49 +11,40 @@ abstract class Zeropage(private val options: CompilationOptions) { private val allocations = mutableMapOf>() val free = mutableListOf() // subclasses must set this to the appropriate free locations. + val allowedDatatypes = NumericDatatypes + fun available() = free.size - fun allocate(name: String, type: DataType) = - allocate(VarDecl(VarDeclType.VAR, type, true, null, name, null, Position("",0,0,0))) - - fun allocate(vardecl: VarDecl) : Int { - assert(vardecl.name.isEmpty() || !allocations.values.any { it.first==vardecl.name } ) {"same name can't be allocated twice"} - assert(vardecl.type== VarDeclType.VAR) {"can only allocate VAR type"} + fun allocate(scopedname: String, datatype: DataType, position: Position?): Int { + assert(scopedname.isEmpty() || !allocations.values.any { it.first==scopedname } ) {"same scopedname can't be allocated twice"} val size = - if(vardecl.arrayspec!=null) { - printWarning("allocating a large value (arrayspec) in zeropage", vardecl.position) - when(vardecl.datatype) { - DataType.UBYTE, DataType.BYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! - DataType.UWORD, DataType.UWORD -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 2 - DataType.FLOAT -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 5 - else -> throw CompilerException("array can only be of byte, word, float") - } - } else { - when (vardecl.datatype) { + when (datatype) { DataType.UBYTE, DataType.BYTE -> 1 DataType.UWORD, DataType.WORD -> 2 DataType.FLOAT -> { if (options.floats) { - printWarning("allocating a large value (float) in zeropage", vardecl.position) + if(position!=null) + printWarning("allocated a large value (float) in zeropage", position) + else + printWarning("$scopedname: allocated a large value (float) in zeropage") 5 } else throw CompilerException("floating point option not enabled") } - else -> throw CompilerException("cannot put datatype ${vardecl.datatype} in zeropage") + else -> throw CompilerException("cannot put datatype $datatype in zeropage") } - } if(free.size > 0) { if(size==1) { for(candidate in free.min()!! .. free.max()!!+1) { if(loneByte(candidate)) - return makeAllocation(candidate, 1, vardecl.datatype, vardecl.name) + return makeAllocation(candidate, 1, datatype, scopedname) } - return makeAllocation(free[0], 1, vardecl.datatype, vardecl.name) + return makeAllocation(free[0], 1, datatype, scopedname) } for(candidate in free.min()!! .. free.max()!!+1) { if (sequentialFree(candidate, size)) - return makeAllocation(candidate, size, vardecl.datatype, vardecl.name) + return makeAllocation(candidate, size, datatype, scopedname) } } diff --git a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt index ad1123124..225319830 100644 --- a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt +++ b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt @@ -45,10 +45,8 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap if (zpVariables.isNotEmpty()) { for (variable in zpVariables) { try { - val address = zeropage.allocate(variable.key, variable.value.type) + val address = zeropage.allocate(variable.key, variable.value.type, null) allocatedZeropageVariables[variable.key] = Pair(address, variable.value.type) - println("DEBUG: allocated on ZP: $variable @ $address") //TODO - block.variablesMarkedForZeropage.remove(variable.key)//TODO weg } catch (x: ZeropageDepletedError) { printWarning(x.toString() + " variable ${variable.key} type ${variable.value.type}") notAllocated++ @@ -56,7 +54,6 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap } } } - println("DEBUG: ${allocatedZeropageVariables.size} variables allocated in Zeropage") // TODO if(notAllocated>0) printWarning("$notAllocated variables marked for Zeropage could not be allocated there") } diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 116f5bd52..ffc08940f 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -62,6 +62,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, program.blocks.clear() program.blocks.addAll(newblocks) + val newAllocatedZp = program.allocatedZeropageVariables.map { symname(it.key, null) to it.value} + program.allocatedZeropageVariables.clear() + program.allocatedZeropageVariables.putAll(newAllocatedZp) + // make a list of all const floats that are used for(block in program.blocks) { for(ins in block.instructions.filter{it.arg?.type==DataType.FLOAT}) { @@ -103,20 +107,27 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } - private fun symname(scoped: String, block: IntermediateProgram.ProgramBlock): String { + private fun symname(scoped: String, block: IntermediateProgram.ProgramBlock?): String { if(' ' in scoped) return scoped - val blockLocal: Boolean - var name = if (scoped.startsWith("${block.shortname}.")) { - blockLocal = true - scoped.substring(block.shortname.length+1) - } else if (scoped.startsWith("block.")) { - blockLocal = false - scoped - } else { - blockLocal = false - scoped + var name = when { + block==null -> { + blockLocal=true + scoped + } + scoped.startsWith("${block.shortname}.") -> { + blockLocal = true + scoped.substring(block.shortname.length+1) + } + scoped.startsWith("block.") -> { + blockLocal = false + scoped + } + else -> { + blockLocal = false + scoped + } } name = name.replace("<<<", "prog8_").replace(">>>", "") if(name=="-") @@ -203,7 +214,29 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, out("* = ${block.address?.toHex()}") } - // @TODO allocate variables on the zeropage as long as there is space + // deal with zeropage variables + for(variable in blk.variables) { + val sym = symname(blk.scopedname+"."+variable.key, null) + val zpVar = program.allocatedZeropageVariables[sym] + if(zpVar==null) { + // This var is not on the ZP yet. Attempt to move it there (if it's not a float, those take up too much space) + if(variable.value.type in zeropage.allowedDatatypes && variable.value.type != DataType.FLOAT) { + try { + val address = zeropage.allocate(sym, variable.value.type, null) + out("${variable.key} = $address\t; zp ${variable.value.type}") + // make sure we add the var to the set of zpvars for this block + blk.variablesMarkedForZeropage.add(variable.key) + program.allocatedZeropageVariables[sym] = Pair(address, variable.value.type) + } catch (x: ZeropageDepletedError) { + // leave it as it is. + } + } + } + else { + // it was already allocated on the zp + out("${variable.key} = ${zpVar.first}\t; zp ${zpVar.second}") + } + } out("\n; memdefs and kernel subroutines") memdefs2asm(block) @@ -235,7 +268,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } private fun vardecls2asm(block: IntermediateProgram.ProgramBlock) { - // these are the non-zeropage variables @todo is this correct now? + // these are the non-zeropage variables val sortedVars = block.variables.filter{it.key !in block.variablesMarkedForZeropage}.toList().sortedBy { it.second.type } for (v in sortedVars) { when (v.second.type) { diff --git a/compiler/src/prog8/compiler/target/c64/Commodore64.kt b/compiler/src/prog8/compiler/target/c64/Commodore64.kt index 41087ed62..6ccb1586a 100644 --- a/compiler/src/prog8/compiler/target/c64/Commodore64.kt +++ b/compiler/src/prog8/compiler/target/c64/Commodore64.kt @@ -25,10 +25,6 @@ const val ESTACK_HI = 0xcf00 // $cf00-$cfff inclusive class C64Zeropage(options: CompilationOptions) : Zeropage(options) { - - // @todo: actually USE the zero page when allocating variables at code generation time - // (ideally, the variables that are used 'most' / inside long loops are allocated in ZP first) - companion object { const val SCRATCH_B1 = 0x02 const val SCRATCH_REG = 0x03 // temp storage for a register diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 114a224d1..06fc502c5 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -139,7 +139,7 @@ fun builtinFunctionReturnType(function: String, args: List, namespa throw FatalAstException("function requires one argument which is an arrayspec $function") } - val func = BuiltinFunctions[function]!! + val func = BuiltinFunctions.getValue(function) if(func.returntype!=null) return func.returntype // function has return values, but the return type depends on the arguments diff --git a/compiler/src/prog8/parser/ModuleParsing.kt b/compiler/src/prog8/parser/ModuleParsing.kt index 362c2ff90..56bace6ee 100644 --- a/compiler/src/prog8/parser/ModuleParsing.kt +++ b/compiler/src/prog8/parser/ModuleParsing.kt @@ -6,7 +6,6 @@ import prog8.compiler.LauncherType import prog8.compiler.OutputType import prog8.determineCompilationOptions import java.io.InputStream -import java.net.URL import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths diff --git a/compiler/test/UnitTests.kt b/compiler/test/UnitTests.kt index d86361fe3..1026ccab7 100644 --- a/compiler/test/UnitTests.kt +++ b/compiler/test/UnitTests.kt @@ -117,36 +117,29 @@ class TestCompiler { } -private val dummypos = Position("test", 0, 0, 0) - - @TestInstance(TestInstance.Lifecycle.PER_CLASS) class TestZeropage { @Test fun testNames() { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false)) + zp.allocate("", DataType.UBYTE, null) + zp.allocate("", DataType.UBYTE, null) + zp.allocate("varname", DataType.UBYTE, null) assertFailsWith { - zp.allocate(VarDecl(VarDeclType.MEMORY, DataType.UBYTE, false, null, "", null, dummypos)) + zp.allocate("varname", DataType.UBYTE, null) } - - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "varname", null, dummypos)) - assertFailsWith { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "varname", null, dummypos)) - } - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "varname2", null, dummypos)) + zp.allocate("varname2", DataType.UBYTE, null) } @Test fun testZpFloatEnable() { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false)) assertFailsWith { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp.allocate("", DataType.FLOAT, null) } val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true)) - zp2.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp2.allocate("", DataType.FLOAT, null) } @Test @@ -187,22 +180,22 @@ class TestZeropage { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true)) assertEquals(19, zp.available()) - zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp.allocate("", DataType.FLOAT, null) assertFailsWith { // in regular zp there aren't 5 sequential bytes free after we take the first sequence - zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp.allocate("", DataType.FLOAT, null) } for (i in 0 until zp.available()) { - val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) + val loc = zp.allocate("", DataType.UBYTE, null) assertTrue(loc > 0) } assertEquals(0, zp.available()) assertFailsWith { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) + zp.allocate("", DataType.UBYTE, null) } assertFailsWith { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos)) + zp.allocate("", DataType.UWORD, null) } } @@ -210,33 +203,33 @@ class TestZeropage { fun testFullAllocation() { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true)) assertEquals(238, zp.available()) - val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + val loc = zp.allocate("", DataType.FLOAT, null) assertTrue(loc > 3) assertFalse(loc in zp.free) val num = zp.available() / 5 val rest = zp.available() % 5 for(i in 0..num-4) { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp.allocate("", DataType.FLOAT, null) } assertEquals(18,zp.available()) assertFailsWith { // can't allocate because no more sequential bytes, only fragmented - zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos)) + zp.allocate("", DataType.FLOAT, null) } for(i in 0..13) { - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) + zp.allocate("", DataType.UBYTE, null) } - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos)) + zp.allocate("", DataType.UWORD, null) assertEquals(2, zp.available()) - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) + zp.allocate("", DataType.UBYTE, null) + zp.allocate("", DataType.UBYTE, null) assertFailsWith { // no more space - zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos)) + zp.allocate("", DataType.UBYTE, null) } } @@ -244,15 +237,15 @@ class TestZeropage { fun testEfficientAllocation() { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true)) assertEquals(19, zp.available()) - assertEquals(0x04, zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, false, null, "", null, dummypos))) - assertEquals(0x09, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos))) - assertEquals(0x0d, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0x94, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0xa7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0xa9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0xb5, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0xf7, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UWORD, false, null, "", null, dummypos))) - assertEquals(0xf9, zp.allocate(VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, "", null, dummypos))) + assertEquals(0x04, zp.allocate("", DataType.FLOAT, null)) + assertEquals(0x09, zp.allocate("", DataType.UBYTE, null)) + assertEquals(0x0d, zp.allocate("", DataType.UWORD, null)) + assertEquals(0x94, zp.allocate("", DataType.UWORD, null)) + assertEquals(0xa7, zp.allocate("", DataType.UWORD, null)) + assertEquals(0xa9, zp.allocate("", DataType.UWORD, null)) + assertEquals(0xb5, zp.allocate("", DataType.UWORD, null)) + assertEquals(0xf7, zp.allocate("", DataType.UWORD, null)) + assertEquals(0xf9, zp.allocate("", DataType.UBYTE, null)) assertEquals(0, zp.available()) } } diff --git a/compiler/test/ValueOperationsTests.kt b/compiler/test/ValueOperationsTests.kt index 5560c779e..969b71c47 100644 --- a/compiler/test/ValueOperationsTests.kt +++ b/compiler/test/ValueOperationsTests.kt @@ -7,7 +7,6 @@ import prog8.ast.LiteralValue import prog8.ast.Position import prog8.compiler.intermediate.Value import prog8.compiler.intermediate.ValueException -import prog8.stackvm.VmExecutionException import kotlin.test.* diff --git a/docs/source/todo.rst b/docs/source/todo.rst index cdd291fe9..67224ceca 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -34,16 +34,9 @@ Add more compiler optimizations to the existing ones. Also some library routines and code patterns could perhaps be optimized further -Should use the zeropage for variables -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Variables should be allocated in the zeropage as long as it has space. -- add some sort of ``zp`` modifier keyword on vardecls to force them into zeropage? - - Misc ^^^^ - sqrt() should have integer implementation as well, instead of relying on float SQRT for all argument types - code generation for POW instruction - +- make sure user-defined blocks come BEFORE library blocks (this helps zeropage variable allocations) diff --git a/examples/rasterbars.p8 b/examples/rasterbars.p8 index 3cf962efb..dac94f363 100644 --- a/examples/rasterbars.p8 +++ b/examples/rasterbars.p8 @@ -26,6 +26,7 @@ Y++ ; delay for alignment Y++ ; delay for alignment Y++ ; delay for alignment + Y++ ; delay for alignment ubyte rasterpos = c64.RASTER if color!=len(colors) { c64.EXTCOL = colors[color] diff --git a/examples/sprites.p8 b/examples/sprites.p8 index e23e8e10f..a50c249e9 100644 --- a/examples/sprites.p8 +++ b/examples/sprites.p8 @@ -56,9 +56,9 @@ sub irq() { c64.EXTCOL-- ; float up & wobble horizontally - for ubyte i in 0 to 14 step 2 { + for ubyte @zp i in 0 to 14 step 2 { c64.SPXY[i+1]-- - ubyte r = rnd() + ubyte @zp r = rnd() if r>200 c64.SPXY[i]++ else if r<40 diff --git a/examples/test.p8 b/examples/test.p8 index 239bcf108..a97099bc6 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,102 +1,35 @@ %import c64utils +%option enable_floats ~ main { - ubyte b1 = 42 - word w = -999 - sub start() { - vm_write_num(b1) - vm_write_char('\n') - vm_write_num(w) - vm_write_char('\n') -; c64scr.print_ub(b1) -; c64.CHROUT('\n') -; c64scr.print_w(w) -; c64.CHROUT('\n') - - b1=0 - w=0 - - vm_write_num(b1) - vm_write_char('\n') - vm_write_num(w) - vm_write_char('\n') - -; c64scr.print_ub(b1) -; c64.CHROUT('\n') -; c64scr.print_w(w) -; c64.CHROUT('\n') - derp.derp() - - } -} + ubyte @zp ub = 22 + byte @zp b = 22 + word @zp w = 2222 + uword @zp uw = 2222 -~ derp { - - ubyte b1 = 55 - - sub derp() { - word w = -999 - vm_write_num(b1) - vm_write_char('\n') - vm_write_num(w) - vm_write_char('\n') - -; c64scr.print_ub(b1) -; c64.CHROUT('\n') -; c64scr.print_w(w) -; c64.CHROUT('\n') - - b1=0 - w=0 - - vm_write_num(b1) - vm_write_char('\n') - vm_write_num(w) - vm_write_char('\n') - -; c64scr.print_ub(b1) -; c64.CHROUT('\n') -; c64scr.print_w(w) -; c64.CHROUT('\n') - + byte nonzp1 = 42 + byte nonzp2 = 42 + byte nonzp3 = 42 + foo.bar() } } +~ foo { -;~ main { -; -; sub start() { -; -; ubyte @zp ub -; byte @zp b -; word @zp w -; uword @zp uw -; -; -; byte nonzp1 -; byte nonzp2 -; byte nonzp3 -; foo.bar() -; } -; -;} -; -;~ foo { -; -;sub bar() { -; ubyte @zp ub -; byte @zp b -; word @zp w -; uword @zp uw -; -; word nonzp1 -; word nonzp2 -; word nonzp3 -; A=55 -;} -;} +sub bar() { + ubyte @zp ub = 33 + byte @zp b = 33 + word @zp w = 3333 + uword @zp uw = 3333 + + word nonzp1 = 4444 + word nonzp2 = 4444 + word nonzp3 = 4444 + A=55 +} +} diff --git a/examples/wizzine.p8 b/examples/wizzine.p8 index 43f2601fd..db9ed4285 100644 --- a/examples/wizzine.p8 +++ b/examples/wizzine.p8 @@ -53,9 +53,9 @@ angle++ c64.MSIGX=0 - for ubyte i in 7 to 0 step -1 { - uword x = sin8u(angle*2-i*16) as uword + 50 - ubyte y = cos8u(angle*3-i*16) / 2 + 70 + for ubyte @zp i in 7 to 0 step -1 { + uword @zp x = sin8u(angle*2-i*16) as uword + 50 + ubyte @zp y = cos8u(angle*3-i*16) / 2 + 70 c64.SPXYW[i] = mkword(lsb(x), y) lsl(c64.MSIGX) if msb(x) c64.MSIGX++