From 02cb237623fa20831537245e2d62eca1c2df828b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 13 Feb 2021 23:04:46 +0100 Subject: [PATCH] added poke() and pokew() builtin functions --- compiler/res/prog8lib/prog8_funcs.asm | 25 +++++++++++++++++++ compiler/res/prog8lib/prog8_lib.asm | 14 ----------- .../compiler/astprocessing/VariousCleanups.kt | 25 +++++++++++++++---- .../compiler/functions/BuiltinFunctions.kt | 2 ++ .../c64/codegen/BuiltinFunctionsAsmGen.kt | 10 +++++++- docs/source/programming.rst | 8 +++++- examples/test.p8 | 10 +++----- syntax-files/IDEA/Prog8.xml | 2 +- 8 files changed, 68 insertions(+), 28 deletions(-) diff --git a/compiler/res/prog8lib/prog8_funcs.asm b/compiler/res/prog8lib/prog8_funcs.asm index a751751a1..4848a069b 100644 --- a/compiler/res/prog8lib/prog8_funcs.asm +++ b/compiler/res/prog8lib/prog8_funcs.asm @@ -1078,3 +1078,28 @@ _loop_hi ldy _index_first .pend +func_peekw .proc + ; -- read the word value on the address in AY + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + ldy #0 + lda (P8ZP_SCRATCH_W1),y + pha + iny + lda (P8ZP_SCRATCH_W1),y + tay + pla + rts + .pend + + +func_pokew .proc + ; -- store the word value in AY in the address in P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_REG + ldy #0 + sta (P8ZP_SCRATCH_W1),y + iny + lda P8ZP_SCRATCH_REG + sta (P8ZP_SCRATCH_W1),y + rts + .pend diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 3dbefccea..4ba193cc7 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -1072,17 +1072,3 @@ sign_extend_AY_byte .proc rts .pend - -peekw .proc - ; -- read the word value on the address in AY - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - ldy #0 - lda (P8ZP_SCRATCH_W1),y - pha - iny - lda (P8ZP_SCRATCH_W1),y - tay - pla - rts - .pend diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index b5782ab30..70da4348a 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -1,13 +1,14 @@ package prog8.compiler.astprocessing +import prog8.ast.IFunctionCall import prog8.ast.INameScope import prog8.ast.Node +import prog8.ast.base.Position import prog8.ast.expressions.DirectMemoryRead import prog8.ast.expressions.FunctionCall import prog8.ast.expressions.NumericLiteralValue import prog8.ast.expressions.TypecastExpression -import prog8.ast.statements.AnonymousScope -import prog8.ast.statements.NopStatement +import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification @@ -46,11 +47,25 @@ internal class VariousCleanups: AstWalker() { return noModifications } + override fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable { + return before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position) + } + override fun before(functionCall: FunctionCall, parent: Node): Iterable { + return before(functionCall as IFunctionCall, parent, functionCall.position) + } + + private fun before(functionCall: IFunctionCall, parent: Node, position: Position): Iterable { if(functionCall.target.nameInSource==listOf("peek")) { - // peek is synonymous with @ - val memread = DirectMemoryRead(functionCall.args.single(), functionCall.position) - return listOf(IAstModification.ReplaceNode(functionCall, memread, parent)) + // peek(a) is synonymous with @(a) + val memread = DirectMemoryRead(functionCall.args.single(), position) + return listOf(IAstModification.ReplaceNode(functionCall as Node, memread, parent)) + } + if(functionCall.target.nameInSource==listOf("poke")) { + // poke(a, v) is synonymous with @(a) = v + val tgt = AssignTarget(null, null, DirectMemoryWrite(functionCall.args[0], position), position) + val assign = Assignment(tgt, functionCall.args[1], position) + return listOf(IAstModification.ReplaceNode(functionCall as Node, assign, parent)) } return noModifications } diff --git a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt index 2de697fae..c9597bbc2 100644 --- a/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/functions/BuiltinFunctions.kt @@ -134,6 +134,8 @@ private val functionSignatures: List = listOf( FSignature("mkword" , true, listOf(FParam("msb", setOf(DataType.UBYTE)), FParam("lsb", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinMkword), FSignature("peek" , true, listOf(FParam("address", setOf(DataType.UWORD))), DataType.UBYTE), FSignature("peekw" , true, listOf(FParam("address", setOf(DataType.UWORD))), DataType.UWORD), + FSignature("poke" , false, listOf(FParam("address", setOf(DataType.UWORD)), FParam("value", setOf(DataType.UBYTE))), null), + FSignature("pokew" , false, listOf(FParam("address", setOf(DataType.UWORD)), FParam("value", setOf(DataType.UWORD))), null), FSignature("rnd" , false, emptyList(), DataType.UBYTE), FSignature("rndw" , false, emptyList(), DataType.UWORD), FSignature("rndf" , false, emptyList(), DataType.FLOAT), diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 398a7ac2d..58139e92b 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -58,6 +58,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val "memory" -> funcMemory(fcall, discardResult, resultToStack, resultRegister) "peekw" -> funcPeekW(fcall, resultToStack, resultRegister) "peek" -> throw AssemblyError("peek() should have been replaced by @()") + "pokew" -> funcPokeW(fcall) + "poke" -> throw AssemblyError("poke() should have been replaced by @()") else -> TODO("missing asmgen for builtin func ${func.name}") } } @@ -960,9 +962,15 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } } + private fun funcPokeW(fcall: IFunctionCall) { + asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", DataType.UWORD, null) + asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.AY) + asmgen.out(" jsr prog8_lib.func_pokew") + } + private fun funcPeekW(fcall: IFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) { asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) - asmgen.out(" jsr prog8_lib.peekw") + asmgen.out(" jsr prog8_lib.func_peekw") if(resultToStack){ asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex") } else { diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 1a60b7e7e..fedb307e5 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -807,7 +807,13 @@ peek(address) same as @(address) - reads the byte at the given address in memory. peekw(address) - reads the word value at the given address in memory. Word is assumed to be stored in usual lsb/msb byte order. + reads the word value at the given address in memory. Word is read as usual little-endian lsb/msb byte order. + +poke(address, value) + same as @(address)=value - writes the byte value at the given address in memory. + +pokew(address, value) + writes the word value at the given address in memory, in usual little-endian lsb/msb byte order. rnd() returns a pseudo-random byte from 0..255 diff --git a/examples/test.p8 b/examples/test.p8 index 24150777c..69942577e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,9 +7,8 @@ main { uword ptr = $4000 - @(ptr) = $34 - @(ptr+1) = $ea - + poke(ptr, $34) + poke(ptr+1, $ea) txt.print_ubhex(peek(ptr), 1) txt.print_ubhex(peek(ptr+1), 1) txt.nl() @@ -18,9 +17,8 @@ main { txt.print_uwhex(ww,1) txt.nl() - ubyte low = peek(ptr) - ubyte high = peek(ptr+1) - ww = mkword(high, low) + pokew(ptr, $98cf) + ww = peekw(ptr) txt.print_uwhex(ww,1) txt.nl() } diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml index 2a92bb898..c0649b4ee 100644 --- a/syntax-files/IDEA/Prog8.xml +++ b/syntax-files/IDEA/Prog8.xml @@ -14,7 +14,7 @@ - +