mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
new ifelse codegen
This commit is contained in:
parent
7d8cdcbfea
commit
577333f2c4
@ -235,7 +235,7 @@ class AsmGen6502Internal (
|
|||||||
private val anyExprGen = AnyExprAsmGen(this)
|
private val anyExprGen = AnyExprAsmGen(this)
|
||||||
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
|
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
|
||||||
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
||||||
private val ifElseAsmgen = IfElseAsmGen(program, this)
|
private val ifElseAsmgen = IfElseAsmGen(program, this, assignmentAsmGen)
|
||||||
|
|
||||||
fun compileToAssembly(): IAssemblyProgram? {
|
fun compileToAssembly(): IAssemblyProgram? {
|
||||||
|
|
||||||
|
@ -2,137 +2,180 @@ package prog8.codegen.cpu6502
|
|||||||
|
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
import prog8.codegen.cpu6502.assignment.AssignmentAsmGen
|
||||||
|
|
||||||
internal class IfElseAsmGen(private val program: PtProgram, private val asmgen: AsmGen6502Internal) {
|
internal class IfElseAsmGen(private val program: PtProgram,
|
||||||
|
private val asmgen: AsmGen6502Internal,
|
||||||
|
private val assignmentAsmGen: AssignmentAsmGen) {
|
||||||
|
|
||||||
fun translate(stmt: PtIfElse) {
|
fun translate(stmt: PtIfElse) {
|
||||||
require(stmt.condition.type== DataType.BOOL)
|
require(stmt.condition.type== DataType.BOOL)
|
||||||
|
|
||||||
if(stmt.ifScope.children.singleOrNull() is PtJump) {
|
val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
|
||||||
translateIfWithOnlyJump(stmt)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
if(stmt.condition is PtIdentifier ||
|
||||||
|
stmt.condition is PtFunctionCall ||
|
||||||
fun translateIfElseBodies(elseBranchInstr: String) {
|
stmt.condition is PtBuiltinFunctionCall ||
|
||||||
if(stmt.hasElse()) {
|
stmt.condition is PtContainmentCheck)
|
||||||
// if and else blocks
|
return fallbackTranslate(stmt, false) // the fallback code for these is optimal, so no warning.
|
||||||
val elseLabel = asmgen.makeLabel("else")
|
|
||||||
asmgen.out(" $elseBranchInstr $elseLabel")
|
|
||||||
asmgen.translate(stmt.ifScope)
|
|
||||||
asmgen.jmp(afterIfLabel, false)
|
|
||||||
asmgen.out(elseLabel)
|
|
||||||
asmgen.translate(stmt.elseScope)
|
|
||||||
} else {
|
|
||||||
// no else block
|
|
||||||
asmgen.out(" $elseBranchInstr $afterIfLabel")
|
|
||||||
asmgen.translate(stmt.ifScope)
|
|
||||||
}
|
|
||||||
asmgen.out(afterIfLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
val compareCond = stmt.condition as? PtBinaryExpression
|
val compareCond = stmt.condition as? PtBinaryExpression
|
||||||
if(compareCond!=null) {
|
if(compareCond!=null) {
|
||||||
if((compareCond.right as? PtNumber)?.number==0.0 && compareCond.operator in arrayOf("==", "!=")) {
|
return when(compareCond.right.type) {
|
||||||
if (compareCond.right.type in ByteDatatypesWithBoolean) {
|
in ByteDatatypesWithBoolean -> translateIfByte(stmt, compareCond, jumpAfterIf)
|
||||||
// equality comparison with 0 TODO temporary optimization
|
in WordDatatypes -> translateIfWord(stmt, compareCond, jumpAfterIf)
|
||||||
val elseBranch = if (compareCond.operator == "==") "bne" else "beq"
|
DataType.FLOAT -> translateIfFloat(stmt, compareCond, jumpAfterIf)
|
||||||
asmgen.assignExpressionToRegister(compareCond.left, RegisterOrPair.A, false)
|
else -> throw AssemblyError("weird dt")
|
||||||
translateIfElseBodies(elseBranch)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO optimize if X comparison Y general case (also with 0 as a special case)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val prefixCond = stmt.condition as? PtPrefix
|
val prefixCond = stmt.condition as? PtPrefix
|
||||||
if(prefixCond?.operator=="not") {
|
if(prefixCond?.operator=="not") {
|
||||||
asmgen.assignExpressionToRegister(prefixCond.value, RegisterOrPair.A, false)
|
assignConditionValueToRegisterAndTest(prefixCond.value)
|
||||||
translateIfElseBodies("bne") // inverted condition, just swap the branches
|
return if(jumpAfterIf!=null)
|
||||||
} else {
|
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||||
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false)
|
else
|
||||||
translateIfElseBodies("beq")
|
translateIfElseBodies("bne", stmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO more optimized ifs
|
||||||
|
println("(if with special condition... ${stmt.condition})")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assignConditionValueToRegisterAndTest(condition: PtExpression) {
|
||||||
|
asmgen.assignExpressionToRegister(condition, RegisterOrPair.A, false)
|
||||||
|
when(condition) {
|
||||||
|
is PtNumber,
|
||||||
|
is PtBool,
|
||||||
|
is PtIdentifier,
|
||||||
|
is PtMachineRegister,
|
||||||
|
is PtArrayIndexer,
|
||||||
|
is PtPrefix,
|
||||||
|
is PtBinaryExpression -> { /* no cmp necessary the lda has been done just prior */ }
|
||||||
|
else -> asmgen.out(" cmp #0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateIfWithOnlyJump(stmt: PtIfElse) {
|
private fun fallbackTranslate(stmt: PtIfElse, warning: Boolean=true) {
|
||||||
val jump = stmt.ifScope.children.single() as PtJump
|
if(warning) println("WARN: FALLBACK IF: ${stmt.position}") // TODO no more of these
|
||||||
val compareCond = stmt.condition as? PtBinaryExpression
|
val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
|
||||||
|
assignConditionValueToRegisterAndTest(stmt.condition)
|
||||||
|
if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("beq", stmt)
|
||||||
|
}
|
||||||
|
|
||||||
fun doJumpAndElse(branchInstr: String, falseBranch: String, jump: PtJump) {
|
private fun translateIfElseBodies(elseBranchInstr: String, stmt: PtIfElse) {
|
||||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
// comparison value is already in A
|
||||||
if(indirect) {
|
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||||
asmgen.out("""
|
if(stmt.hasElse()) {
|
||||||
|
// if and else blocks
|
||||||
|
val elseLabel = asmgen.makeLabel("else")
|
||||||
|
asmgen.out(" $elseBranchInstr $elseLabel")
|
||||||
|
asmgen.translate(stmt.ifScope)
|
||||||
|
asmgen.jmp(afterIfLabel, false)
|
||||||
|
asmgen.out(elseLabel)
|
||||||
|
asmgen.translate(stmt.elseScope)
|
||||||
|
} else {
|
||||||
|
// no else block
|
||||||
|
asmgen.out(" $elseBranchInstr $afterIfLabel")
|
||||||
|
asmgen.translate(stmt.ifScope)
|
||||||
|
}
|
||||||
|
asmgen.out(afterIfLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateJumpElseBodies(branchInstr: String, falseBranch: String, jump: PtJump, elseBlock: PtNodeGroup) {
|
||||||
|
// comparison value is already in A
|
||||||
|
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||||
|
if(indirect) {
|
||||||
|
asmgen.out("""
|
||||||
$falseBranch +
|
$falseBranch +
|
||||||
jmp ($asmLabel)
|
jmp ($asmLabel)
|
||||||
+ """)
|
+""")
|
||||||
} else {
|
} else {
|
||||||
asmgen.out(" $branchInstr $asmLabel")
|
asmgen.out(" $branchInstr $asmLabel")
|
||||||
}
|
|
||||||
if(stmt.hasElse())
|
|
||||||
asmgen.translate(stmt.elseScope)
|
|
||||||
}
|
}
|
||||||
|
asmgen.translate(elseBlock)
|
||||||
if(compareCond!=null) {
|
|
||||||
if (compareCond.operator in arrayOf("==", "!=")) {
|
|
||||||
val compareNumber = compareCond.right as? PtNumber
|
|
||||||
when (compareCond.right.type) {
|
|
||||||
in ByteDatatypesWithBoolean -> {
|
|
||||||
asmgen.assignExpressionToRegister(compareCond.left, RegisterOrPair.A, false)
|
|
||||||
if(compareNumber==null || compareNumber.number!=0.0)
|
|
||||||
compareRegisterAwithByte(compareCond.right)
|
|
||||||
if(compareCond.operator=="==") {
|
|
||||||
// if X==something goto blah
|
|
||||||
doJumpAndElse("beq", "bne", jump)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
// if X!=something goto blah
|
|
||||||
doJumpAndElse("bne", "brq", jump)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
in WordDatatypes -> {
|
|
||||||
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false)
|
|
||||||
doJumpAndElse("bne", "beq", jump)
|
|
||||||
return
|
|
||||||
// TODO: optimize word
|
|
||||||
// assignExpressionToRegister(compareCond.left, RegisterOrPair.AY, false)
|
|
||||||
// compareRegisterAYwithWord(compareCond.operator, compareCond.right, jump)
|
|
||||||
// if(compareCond.operator=="==") {
|
|
||||||
// // if X==something goto blah
|
|
||||||
// doJumpAndElse("beq", "bne", jump)
|
|
||||||
// return
|
|
||||||
// } else {
|
|
||||||
// // if X!=something goto blah
|
|
||||||
// doJumpAndElse("bne", "brq", jump)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
DataType.FLOAT -> {
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
throw AssemblyError("weird dt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asmgen.assignExpressionToRegister(stmt.condition, RegisterOrPair.A, false)
|
|
||||||
doJumpAndElse("bne", "beq", jump)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compareRegisterAwithByte(value: PtExpression) {
|
private fun translateIfByte(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
|
||||||
fun cmpViaScratch() {
|
val signed = condition.left.type in SignedDatatypes
|
||||||
if(!value.isSimple()) asmgen.out(" pha")
|
val constValue = condition.right.asConstInteger()
|
||||||
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", value.type)
|
if(constValue==0) {
|
||||||
if(!value.isSimple()) asmgen.out(" pla")
|
if(condition.operator=="==") {
|
||||||
asmgen.out(" cmp P8ZP_SCRATCH_REG")
|
// if X==0
|
||||||
|
assignConditionValueToRegisterAndTest(condition.left)
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("bne", stmt)
|
||||||
|
} else if(condition.operator=="!=") {
|
||||||
|
// if X!=0
|
||||||
|
assignConditionValueToRegisterAndTest(condition.left)
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("beq", stmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO how is if X==pointeervar[99] translated? can use cmp indirect indexed
|
when (condition.operator) {
|
||||||
|
"==" -> {
|
||||||
|
// if X==value
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||||
|
cmpAwithByteValue(condition.right)
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("bne", stmt)
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
// if X!=value
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||||
|
cmpAwithByteValue(condition.right)
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("beq", stmt)
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
// TODO()
|
||||||
|
println("byte if <")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("byte if <=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
// TODO()
|
||||||
|
println("byte if >")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("byte if >=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
else -> fallbackTranslate(stmt, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cmpAwithByteValue(value: PtExpression) {
|
||||||
|
fun cmpViaScratch() {
|
||||||
|
if(assignmentAsmGen.directIntoY(value)) {
|
||||||
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.Y, false)
|
||||||
|
asmgen.out(" sty P8ZP_SCRATCH_REG")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" pha")
|
||||||
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_REG", value.type)
|
||||||
|
asmgen.out(" pla")
|
||||||
|
}
|
||||||
|
asmgen.out(" cmp P8ZP_SCRATCH_REG")
|
||||||
|
}
|
||||||
|
|
||||||
when(value) {
|
when(value) {
|
||||||
is PtArrayIndexer -> {
|
is PtArrayIndexer -> {
|
||||||
@ -140,8 +183,7 @@ internal class IfElseAsmGen(private val program: PtProgram, private val asmgen:
|
|||||||
if(constIndex!=null) {
|
if(constIndex!=null) {
|
||||||
val offset = constIndex * program.memsizer.memorySize(value.type)
|
val offset = constIndex * program.memsizer.memorySize(value.type)
|
||||||
if(offset<256) {
|
if(offset<256) {
|
||||||
asmgen.out(" ldy #$offset | cmp ${asmgen.asmVariableName(value.variable.name)},y")
|
return asmgen.out(" ldy #$offset | cmp ${asmgen.asmVariableName(value.variable.name)},y")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmpViaScratch()
|
cmpViaScratch()
|
||||||
@ -167,4 +209,120 @@ internal class IfElseAsmGen(private val program: PtProgram, private val asmgen:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translateIfWord(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
|
||||||
|
val signed = condition.left.type in SignedDatatypes
|
||||||
|
val constValue = condition.right.asConstInteger()
|
||||||
|
if(constValue==0) {
|
||||||
|
if(condition.operator=="==") {
|
||||||
|
// if X==0
|
||||||
|
// TODO even more optimized code by comparing lsb and msb separately
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
|
||||||
|
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("bne", stmt)
|
||||||
|
} else if(condition.operator=="!=") {
|
||||||
|
// if X!=0
|
||||||
|
// TODO even more optimized code by comparing lsb and msb separately
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
|
||||||
|
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
|
||||||
|
return if(jumpAfterIf!=null)
|
||||||
|
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("beq", stmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(condition.operator) {
|
||||||
|
"==" -> {
|
||||||
|
// TODO
|
||||||
|
println("word if ==")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
// TODO
|
||||||
|
println("word if !=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
// TODO()
|
||||||
|
println("word if <")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("word if <=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
// TODO()
|
||||||
|
println("word if >")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("word if >=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
else -> fallbackTranslate(stmt, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateIfFloat(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
|
||||||
|
val constValue = (condition.right as? PtNumber)?.number
|
||||||
|
if(constValue==0.0) {
|
||||||
|
if (condition.operator == "==") {
|
||||||
|
// if FL==0.0
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.FAC1, true)
|
||||||
|
asmgen.out(" jsr floats.SIGN | cmp #0")
|
||||||
|
return if (jumpAfterIf != null)
|
||||||
|
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("bne", stmt)
|
||||||
|
} else if(condition.operator=="!=") {
|
||||||
|
// if FL!=0.0
|
||||||
|
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.FAC1, true)
|
||||||
|
asmgen.out(" jsr floats.SIGN | cmp #0")
|
||||||
|
return if (jumpAfterIf != null)
|
||||||
|
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||||
|
else
|
||||||
|
translateIfElseBodies("beq", stmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(condition.operator) {
|
||||||
|
"==" -> {
|
||||||
|
// TODO
|
||||||
|
println("float if ==")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
// TODO
|
||||||
|
println("float if !=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
// TODO()
|
||||||
|
println("float if <")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("float if <=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
// TODO()
|
||||||
|
println("float if >")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
// TODO()
|
||||||
|
println("float if >=")
|
||||||
|
fallbackTranslate(stmt)
|
||||||
|
}
|
||||||
|
else -> fallbackTranslate(stmt, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -568,7 +568,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun directIntoY(expr: PtExpression): Boolean {
|
internal fun directIntoY(expr: PtExpression): Boolean {
|
||||||
return when(expr) {
|
return when(expr) {
|
||||||
is PtIdentifier -> true
|
is PtIdentifier -> true
|
||||||
is PtMachineRegister -> true
|
is PtMachineRegister -> true
|
||||||
|
@ -556,7 +556,7 @@ asmsub mouse_config2(byte shape @A) clobbers (A, X, Y) {
|
|||||||
|
|
||||||
asmsub mouse_pos() clobbers(X) -> ubyte @A {
|
asmsub mouse_pos() clobbers(X) -> ubyte @A {
|
||||||
; -- short wrapper around mouse_get() kernal routine:
|
; -- short wrapper around mouse_get() kernal routine:
|
||||||
; -- gets the position of the mouse cursor in cx16.r0 and cx16.r1 (x/y coordinate), returns mouse button status.
|
; -- gets the position of the mouse cursor in cx16.r0 and cx16.r1 (x/y coordinate), returns mouse button status in A.
|
||||||
%asm {{
|
%asm {{
|
||||||
ldx #cx16.r0
|
ldx #cx16.r0
|
||||||
jmp cx16.mouse_get
|
jmp cx16.mouse_get
|
||||||
|
@ -5,11 +5,11 @@ package prog8.buildversion
|
|||||||
*/
|
*/
|
||||||
const val MAVEN_GROUP = "prog8"
|
const val MAVEN_GROUP = "prog8"
|
||||||
const val MAVEN_NAME = "compiler"
|
const val MAVEN_NAME = "compiler"
|
||||||
const val VERSION = "10.2-SNAPSHOT"
|
const val VERSION = "10.2-BOOLEANS"
|
||||||
const val GIT_REVISION = 4459
|
const val GIT_REVISION = 4485
|
||||||
const val GIT_SHA = "a1f197d2ff2e23c84cac26efbda75ef3efb1f0aa"
|
const val GIT_SHA = "eddf97191959f87119c746d8833b71a247db661d"
|
||||||
const val GIT_DATE = "2024-02-10T00:33:26Z"
|
const val GIT_DATE = "2024-02-15T23:58:56Z"
|
||||||
const val GIT_BRANCH = "master"
|
const val GIT_BRANCH = "booleans"
|
||||||
const val BUILD_DATE = "2024-02-10T00:33:30Z"
|
const val BUILD_DATE = "2024-02-16T00:19:00Z"
|
||||||
const val BUILD_UNIX_TIME = 1707525210318L
|
const val BUILD_UNIX_TIME = 1708042740125L
|
||||||
const val DIRTY = 0
|
const val DIRTY = 1
|
||||||
|
@ -55,7 +55,6 @@ boolean trick to go from a compare >= value, to a bool
|
|||||||
and #1
|
and #1
|
||||||
|
|
||||||
|
|
||||||
Chess: cannot click mouse to start. nothing happens.
|
|
||||||
Already broken in 10.0: textelite on c64, info on diso -> jams the cpu after printing
|
Already broken in 10.0: textelite on c64, info on diso -> jams the cpu after printing
|
||||||
|
|
||||||
IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register.
|
IR: add TEST instruction to test memory content and set N/Z flags, without affecting any register.
|
||||||
|
186
examples/test.p8
186
examples/test.p8
@ -8,6 +8,15 @@ main {
|
|||||||
bool @shared staticbool2
|
bool @shared staticbool2
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
cx16.mouse_config2(1) ; enable mouse cursor (sprite 0)
|
||||||
|
while cx16.mouse_pos()==0 {
|
||||||
|
cx16.r0L++
|
||||||
|
}
|
||||||
|
while cx16.mouse_pos()!=0 {
|
||||||
|
cx16.r0L++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
; boolean_const_and_var(true)
|
; boolean_const_and_var(true)
|
||||||
; staticbool1 = boolean_arrays_and_return()
|
; staticbool1 = boolean_arrays_and_return()
|
||||||
; txt.print_ub(staticbool1 as ubyte)
|
; txt.print_ub(staticbool1 as ubyte)
|
||||||
@ -25,9 +34,11 @@ main {
|
|||||||
; while_bool_efficient()
|
; while_bool_efficient()
|
||||||
; efficient_compare_0()
|
; efficient_compare_0()
|
||||||
; efficient_compare_99()
|
; efficient_compare_99()
|
||||||
|
; efficient_compare_var()
|
||||||
; efficient_assign_cmp_0()
|
; efficient_assign_cmp_0()
|
||||||
; efficient_assign_cmp_99()
|
; efficient_assign_cmp_99()
|
||||||
if_gotos()
|
; efficient_assign_cmp_var()
|
||||||
|
; if_gotos()
|
||||||
; if_code()
|
; if_code()
|
||||||
;;sys.exit(1)
|
;;sys.exit(1)
|
||||||
; while_equiv()
|
; while_equiv()
|
||||||
@ -52,16 +63,16 @@ main {
|
|||||||
|
|
||||||
sub while_bool_efficient() {
|
sub while_bool_efficient() {
|
||||||
while staticbool1 {
|
while staticbool1 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while not staticbool1 {
|
while not staticbool1 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while cx16.r0L==0 {
|
while cx16.r0L==0 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while cx16.r0L!=0 {
|
while cx16.r0L!=0 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,29 +106,49 @@ main {
|
|||||||
bb2 = fl!=99.0
|
bb2 = fl!=99.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub efficient_assign_cmp_var() {
|
||||||
|
ubyte @shared ub
|
||||||
|
uword @shared uw
|
||||||
|
float @shared fl
|
||||||
|
bool @shared bb1, bb2
|
||||||
|
float @shared fval
|
||||||
|
|
||||||
|
bb1 = ub==cx16.r0L
|
||||||
|
bb2 = ub!=cx16.r0L
|
||||||
|
bb1 = uw==cx16.r0
|
||||||
|
bb2 = uw!=cx16.r0
|
||||||
|
bb1 = fl==0.0
|
||||||
|
bb2 = fl!=0.0
|
||||||
|
bb1 = fl==fval
|
||||||
|
bb2 = fl!=fval
|
||||||
|
|
||||||
|
bb1 = bb2==uw[cx16.r0L]
|
||||||
|
bb2 = bb1!=uw[cx16.r1L]
|
||||||
|
}
|
||||||
|
|
||||||
sub efficient_compare_0() {
|
sub efficient_compare_0() {
|
||||||
ubyte @shared ub
|
ubyte @shared ub
|
||||||
uword @shared uw
|
uword @shared uw
|
||||||
float @shared fl
|
float @shared fl
|
||||||
|
|
||||||
if ub==0
|
if ub==0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if uw==0
|
if uw==0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if fl==0
|
if fl==0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if ub!=0
|
if ub!=0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
if uw!=0
|
if uw!=0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
if fl!=0
|
if fl!=0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
}
|
}
|
||||||
|
|
||||||
sub efficient_compare_99() {
|
sub efficient_compare_99() {
|
||||||
@ -126,23 +157,63 @@ main {
|
|||||||
float @shared fl
|
float @shared fl
|
||||||
|
|
||||||
if ub==99
|
if ub==99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if uw==99
|
if uw==99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if fl==99.99
|
if fl==99.99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if ub!=99
|
if ub!=99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
if uw!=99
|
if uw!=99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
if fl!=99.99
|
if fl!=99.99
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r1++
|
cx16.r1L++
|
||||||
|
}
|
||||||
|
|
||||||
|
sub efficient_compare_var() {
|
||||||
|
ubyte @shared ub
|
||||||
|
uword @shared uw
|
||||||
|
float @shared fl
|
||||||
|
float @shared fval
|
||||||
|
|
||||||
|
if ub==cx16.r0L
|
||||||
|
cx16.r0L++
|
||||||
|
if uw==cx16.r0
|
||||||
|
cx16.r0L++
|
||||||
|
if fl==fval
|
||||||
|
cx16.r0L++
|
||||||
|
if fl==0.0
|
||||||
|
cx16.r0L++
|
||||||
|
if ub!=cx16.r0L
|
||||||
|
cx16.r0L++
|
||||||
|
else
|
||||||
|
cx16.r1L++
|
||||||
|
if uw!=cx16.r0
|
||||||
|
cx16.r0L++
|
||||||
|
else
|
||||||
|
cx16.r1L++
|
||||||
|
if fl!=fval
|
||||||
|
cx16.r0L++
|
||||||
|
else
|
||||||
|
cx16.r1L++
|
||||||
|
if fl!=0.0
|
||||||
|
cx16.r0L++
|
||||||
|
else
|
||||||
|
cx16.r1L++
|
||||||
|
|
||||||
|
if ub==uw[cx16.r0L]
|
||||||
|
cx16.r0L++
|
||||||
|
if ub!=uw[cx16.r0L]
|
||||||
|
cx16.r0L++
|
||||||
|
|
||||||
|
if staticbool2 or staticbool1
|
||||||
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
|
|
||||||
sub logical_operand_swap() {
|
sub logical_operand_swap() {
|
||||||
@ -264,29 +335,29 @@ main {
|
|||||||
;
|
;
|
||||||
; sub while_until_int_errors() {
|
; sub while_until_int_errors() {
|
||||||
;; while staticbool1==42 {
|
;; while staticbool1==42 {
|
||||||
;; cx16.r0++
|
;; cx16.r0L++
|
||||||
;; }
|
;; }
|
||||||
;;
|
;;
|
||||||
;; do {
|
;; do {
|
||||||
;; cx16.r0++
|
;; cx16.r0L++
|
||||||
;; } until staticbool1==42
|
;; } until staticbool1==42
|
||||||
;
|
;
|
||||||
; ubyte @shared ub1
|
; ubyte @shared ub1
|
||||||
;
|
;
|
||||||
; while not ub1 {
|
; while not ub1 {
|
||||||
; cx16.r0++
|
; cx16.r0L++
|
||||||
; }
|
; }
|
||||||
;
|
;
|
||||||
; while intfunc() {
|
; while intfunc() {
|
||||||
; cx16.r0++
|
; cx16.r0L++
|
||||||
; }
|
; }
|
||||||
;
|
;
|
||||||
; while not intfunc() {
|
; while not intfunc() {
|
||||||
; cx16.r0++
|
; cx16.r0L++
|
||||||
; }
|
; }
|
||||||
;
|
;
|
||||||
;; while not cx16.mouse_pos() {
|
;; while not cx16.mouse_pos() {
|
||||||
;; cx16.r0++
|
;; cx16.r0L++
|
||||||
;; }
|
;; }
|
||||||
; }
|
; }
|
||||||
|
|
||||||
@ -295,16 +366,16 @@ main {
|
|||||||
bool @shared bb
|
bool @shared bb
|
||||||
|
|
||||||
while bb {
|
while bb {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while ub!=0 {
|
while ub!=0 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while not bb {
|
while not bb {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
while ub==0 {
|
while ub==0 {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +411,7 @@ main {
|
|||||||
|
|
||||||
sub bools_in_array_assigns_inplace() {
|
sub bools_in_array_assigns_inplace() {
|
||||||
bool[] ba = [true, false, true]
|
bool[] ba = [true, false, true]
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
ba[1] = ba[1] xor staticbool2
|
ba[1] = ba[1] xor staticbool2
|
||||||
ba[2] = staticbool2 xor ba[2]
|
ba[2] = staticbool2 xor ba[2]
|
||||||
ba[1] = ba[1] and staticbool2
|
ba[1] = ba[1] and staticbool2
|
||||||
@ -374,32 +445,37 @@ main {
|
|||||||
if_cc
|
if_cc
|
||||||
goto label
|
goto label
|
||||||
else
|
else
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if_cs
|
if_cs
|
||||||
goto label
|
goto label
|
||||||
else
|
else
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
|
|
||||||
|
|
||||||
if ub==0
|
|
||||||
goto label
|
|
||||||
if ub!=0
|
|
||||||
goto label
|
|
||||||
if not ub==99
|
if not ub==99
|
||||||
goto label
|
goto label
|
||||||
|
|
||||||
if ub==0
|
if ub==0
|
||||||
goto label
|
goto label
|
||||||
else
|
|
||||||
cx16.r0++
|
|
||||||
if ub!=0
|
if ub!=0
|
||||||
goto label
|
goto label
|
||||||
else
|
|
||||||
cx16.r0++
|
|
||||||
if not ub==98
|
if not ub==98
|
||||||
goto label
|
goto label
|
||||||
else
|
else
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
|
if ub==0
|
||||||
|
goto label
|
||||||
|
else
|
||||||
|
cx16.r0L++
|
||||||
|
if ub!=0
|
||||||
|
goto label
|
||||||
|
else
|
||||||
|
cx16.r0L++
|
||||||
|
|
||||||
|
if staticbool1
|
||||||
|
goto label
|
||||||
|
if not staticbool2
|
||||||
|
goto label
|
||||||
label:
|
label:
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,28 +483,28 @@ main {
|
|||||||
ubyte @shared ub
|
ubyte @shared ub
|
||||||
bool @shared bb
|
bool @shared bb
|
||||||
if ub==0
|
if ub==0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if ub!=0
|
if ub!=0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if bb
|
if bb
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
if not bb
|
if not bb
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
|
|
||||||
if ub==0
|
if ub==0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r0--
|
cx16.r0--
|
||||||
if ub!=0
|
if ub!=0
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r0--
|
cx16.r0--
|
||||||
if bb
|
if bb
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r0--
|
cx16.r0--
|
||||||
if not bb
|
if not bb
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
else
|
else
|
||||||
cx16.r0--
|
cx16.r0--
|
||||||
}
|
}
|
||||||
@ -438,6 +514,6 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub voidfuncub(ubyte arg) {
|
sub voidfuncub(ubyte arg) {
|
||||||
cx16.r0++
|
cx16.r0L++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user