mirror of
https://github.com/irmen/prog8.git
synced 2024-07-10 23:29:02 +00:00
added peek() and peekw() builtin functions
This commit is contained in:
parent
4fff150c7b
commit
cc0f19653e
@ -1071,3 +1071,18 @@ sign_extend_AY_byte .proc
|
||||
pla
|
||||
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
|
||||
|
@ -2,6 +2,8 @@ package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.INameScope
|
||||
import prog8.ast.Node
|
||||
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
|
||||
@ -43,4 +45,14 @@ internal class VariousCleanups: AstWalker() {
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
|
||||
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))
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,6 +132,8 @@ private val functionSignatures: List<FSignature> = listOf(
|
||||
FSignature("lsb" , true, listOf(FParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x and 255 } },
|
||||
FSignature("msb" , true, listOf(FParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x ushr 8 and 255} },
|
||||
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("rnd" , false, emptyList(), DataType.UBYTE),
|
||||
FSignature("rndw" , false, emptyList(), DataType.UWORD),
|
||||
FSignature("rndf" , false, emptyList(), DataType.FLOAT),
|
||||
|
@ -56,6 +56,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
"sort" -> funcSort(fcall)
|
||||
"reverse" -> funcReverse(fcall)
|
||||
"memory" -> funcMemory(fcall, discardResult, resultToStack, resultRegister)
|
||||
"peekw" -> funcPeekW(fcall, resultToStack, resultRegister)
|
||||
"peek" -> throw AssemblyError("peek() should have been replaced by @()")
|
||||
else -> TODO("missing asmgen for builtin func ${func.name}")
|
||||
}
|
||||
}
|
||||
@ -958,6 +960,22 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPeekW(fcall: IFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.peekw")
|
||||
if(resultToStack){
|
||||
asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex")
|
||||
} else {
|
||||
when(resultRegister ?: RegisterOrPair.AY) {
|
||||
RegisterOrPair.AY -> {}
|
||||
RegisterOrPair.AX -> asmgen.out(" sty P8ZP_SCRATCH_REG | ldx P8ZP_SCRATCH_REG")
|
||||
RegisterOrPair.XY -> asmgen.out(" tax")
|
||||
in Cx16VirtualRegisters -> asmgen.out(" sta cx16.${resultRegister.toString().toLowerCase()} | sty cx16.${resultRegister.toString().toLowerCase()}+1")
|
||||
else -> throw AssemblyError("invalid reg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcMkword(fcall: IFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
|
||||
if(resultToStack) {
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.Y) // msb
|
||||
|
@ -413,10 +413,6 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
|
||||
outputlni("}}")
|
||||
}
|
||||
|
||||
override fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder) {
|
||||
output(builtinFunctionStatementPlaceholder.name)
|
||||
}
|
||||
|
||||
override fun visit(whenStatement: WhenStatement) {
|
||||
output("when ")
|
||||
whenStatement.condition.accept(this)
|
||||
|
@ -34,8 +34,8 @@ sealed class Statement : Node {
|
||||
class BuiltinFunctionStatementPlaceholder(val name: String, override val position: Position) : Statement() {
|
||||
override var parent: Node = ParentSentinel
|
||||
override fun linkParents(parent: Node) {}
|
||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
||||
override fun accept(visitor: IAstVisitor) = throw FatalAstException("should not iterate over this node")
|
||||
override fun accept(visitor: AstWalker, parent: Node) = throw FatalAstException("should not iterate over this node")
|
||||
override fun definingScope(): INameScope = BuiltinFunctionScopePlaceholder
|
||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||
replacement.parent = this
|
||||
|
@ -84,7 +84,6 @@ abstract class AstWalker {
|
||||
open fun before(block: Block, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(branchStatement: BranchStatement, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(decl: VarDecl, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(directive: Directive, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
open fun before(expr: BinaryExpression, parent: Node): Iterable<IAstModification> = emptyList()
|
||||
@ -395,11 +394,6 @@ abstract class AstWalker {
|
||||
track(after(inlineAssembly, parent), inlineAssembly, parent)
|
||||
}
|
||||
|
||||
fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node) {
|
||||
track(before(builtinFunctionStatementPlaceholder, parent), builtinFunctionStatementPlaceholder, parent)
|
||||
track(after(builtinFunctionStatementPlaceholder, parent), builtinFunctionStatementPlaceholder, parent)
|
||||
}
|
||||
|
||||
fun visit(nopStatement: NopStatement, parent: Node) {
|
||||
track(before(nopStatement, parent), nopStatement, parent)
|
||||
track(after(nopStatement, parent), nopStatement, parent)
|
||||
|
@ -158,9 +158,6 @@ interface IAstVisitor {
|
||||
fun visit(inlineAssembly: InlineAssembly) {
|
||||
}
|
||||
|
||||
fun visit(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder) {
|
||||
}
|
||||
|
||||
fun visit(nopStatement: NopStatement) {
|
||||
}
|
||||
|
||||
|
@ -803,6 +803,11 @@ mkword(msb, lsb)
|
||||
Don't get confused by how the system actually stores this 16-bit word value in memory (which is
|
||||
in little-endian format, so lsb first then msb)
|
||||
|
||||
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.
|
||||
|
||||
rnd()
|
||||
returns a pseudo-random byte from 0..255
|
||||
|
@ -10,16 +10,16 @@ main {
|
||||
@(ptr) = $34
|
||||
@(ptr+1) = $ea
|
||||
|
||||
txt.print_ubhex(@(ptr), 1)
|
||||
txt.print_ubhex(@(ptr+1), 1)
|
||||
txt.print_ubhex(peek(ptr), 1)
|
||||
txt.print_ubhex(peek(ptr+1), 1)
|
||||
txt.nl()
|
||||
|
||||
uword ww = mkword(@(ptr+1), @(ptr)) ; TODO FIX
|
||||
uword ww = peekw(ptr)
|
||||
txt.print_uwhex(ww,1)
|
||||
txt.nl()
|
||||
|
||||
ubyte low = @(ptr)
|
||||
ubyte high = @(ptr+1)
|
||||
ubyte low = peek(ptr)
|
||||
ubyte high = peek(ptr+1)
|
||||
ww = mkword(high, low)
|
||||
txt.print_uwhex(ww,1)
|
||||
txt.nl()
|
||||
|
Loading…
Reference in New Issue
Block a user