mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
fix parameter passing bug introduced recently (byte not converted to word)
This commit is contained in:
parent
16b24fadea
commit
d54ab856e7
@ -563,7 +563,7 @@ class AsmGen6502Internal (
|
||||
when(reg) {
|
||||
RegisterOrPair.A,
|
||||
RegisterOrPair.X,
|
||||
RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister(), target.datatype in SignedDatatypes)
|
||||
RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister(), target.datatype in SignedDatatypes, true)
|
||||
RegisterOrPair.AX,
|
||||
RegisterOrPair.AY,
|
||||
RegisterOrPair.XY,
|
||||
|
@ -110,8 +110,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
val var3name = asmgen.asmVariableName(fcall.args[3] as PtIdentifier)
|
||||
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name)
|
||||
val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[3].position, var3name)
|
||||
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false)
|
||||
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false)
|
||||
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false, false)
|
||||
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false, false)
|
||||
}
|
||||
|
||||
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
|
||||
@ -273,11 +273,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when(fcall.args[0].type) {
|
||||
DataType.UBYTE -> {
|
||||
asmgen.out(" ldy #0 | jsr prog8_lib.func_sqrt16_into_A")
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false)
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false, false)
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false)
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false, false)
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out(" jsr floats.func_sqrt_into_FAC1")
|
||||
@ -686,7 +686,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
assignAsmGen.assignConstantByte(target, 0)
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A, false)
|
||||
assignAsmGen.assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignAsmGen.assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -701,7 +701,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A")
|
||||
else -> throw AssemblyError("weird type $dt")
|
||||
}
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, true)
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, true, true)
|
||||
}
|
||||
|
||||
private fun funcAnyAll(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
|
||||
@ -714,7 +714,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
in SplitWordArrayTypes -> TODO("split word any/all")
|
||||
else -> throw AssemblyError("weird type $dt")
|
||||
}
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes)
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes, true)
|
||||
}
|
||||
|
||||
private fun funcAbs(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
|
||||
@ -723,7 +723,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when (dt) {
|
||||
DataType.BYTE -> {
|
||||
asmgen.out(" jsr prog8_lib.abs_b_into_A")
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A,false)
|
||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A,false, true)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
asmgen.out(" jsr prog8_lib.abs_w_into_AY")
|
||||
@ -871,7 +871,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A, signed) // value
|
||||
asmgen.out(" jsr prog8_lib.func_clamp_${fcall.type.toString().lowercase()}")
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
|
||||
assignAsmGen.assignRegisterByte(targetReg, CpuRegister.A, signed)
|
||||
assignAsmGen.assignRegisterByte(targetReg, CpuRegister.A, signed, true)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W1", fcall.args[1].type) // minimum
|
||||
@ -887,55 +887,59 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
|
||||
private fun funcMin(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||
val signed = fcall.type in SignedDatatypes
|
||||
if(fcall.type in ByteDatatypes) {
|
||||
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left
|
||||
asmgen.out(" cmp P8ZP_SCRATCH_B1")
|
||||
if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +")
|
||||
asmgen.out("""
|
||||
lda P8ZP_SCRATCH_B1
|
||||
+""")
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
|
||||
asmgen.assignRegister(RegisterOrPair.A, targetReg)
|
||||
} else if(fcall.type in WordDatatypes) {
|
||||
asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left
|
||||
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
|
||||
if(signed) {
|
||||
when (fcall.type) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_B1", fcall.type) // right
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // left
|
||||
asmgen.out(" cmp P8ZP_SCRATCH_B1")
|
||||
if(signed) asmgen.out(" bmi +") else asmgen.out(" bcc +")
|
||||
asmgen.out("""
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
cmp P8ZP_SCRATCH_W2
|
||||
tya
|
||||
sbc P8ZP_SCRATCH_W2+1
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bpl +
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
jmp ++
|
||||
+ lda P8ZP_SCRATCH_W2
|
||||
ldy P8ZP_SCRATCH_W2+1
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
lda P8ZP_SCRATCH_W1+1
|
||||
cmp P8ZP_SCRATCH_W2+1
|
||||
bcc ++
|
||||
bne +
|
||||
lda P8ZP_SCRATCH_W1
|
||||
cmp P8ZP_SCRATCH_W2
|
||||
bcc ++
|
||||
+ lda P8ZP_SCRATCH_W2
|
||||
ldy P8ZP_SCRATCH_W2+1
|
||||
jmp ++
|
||||
+ lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
+""")
|
||||
lda P8ZP_SCRATCH_B1
|
||||
+""")
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, signed, fcall.position, fcall.definingISub(), asmgen)
|
||||
asmgen.assignRegister(RegisterOrPair.A, targetReg)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
asmgen.assignExpressionToVariable(fcall.args[0], "P8ZP_SCRATCH_W1", fcall.type) // left
|
||||
asmgen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", fcall.type) // right
|
||||
if(signed) {
|
||||
asmgen.out("""
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
cmp P8ZP_SCRATCH_W2
|
||||
tya
|
||||
sbc P8ZP_SCRATCH_W2+1
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bpl +
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
jmp ++
|
||||
+ lda P8ZP_SCRATCH_W2
|
||||
ldy P8ZP_SCRATCH_W2+1
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
lda P8ZP_SCRATCH_W1+1
|
||||
cmp P8ZP_SCRATCH_W2+1
|
||||
bcc ++
|
||||
bne +
|
||||
lda P8ZP_SCRATCH_W1
|
||||
cmp P8ZP_SCRATCH_W2
|
||||
bcc ++
|
||||
+ lda P8ZP_SCRATCH_W2
|
||||
ldy P8ZP_SCRATCH_W2+1
|
||||
jmp ++
|
||||
+ lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
+""")
|
||||
}
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, signed, fcall.position, fcall.definingISub(), asmgen)
|
||||
asmgen.assignRegister(RegisterOrPair.AY, targetReg)
|
||||
}
|
||||
else -> {
|
||||
throw AssemblyError("min float not supported")
|
||||
}
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, signed, fcall.position, fcall.definingISub(), asmgen)
|
||||
asmgen.assignRegister(RegisterOrPair.AY, targetReg)
|
||||
} else {
|
||||
throw AssemblyError("min float not supported")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
||||
}
|
||||
}
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
when (elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(" lda $arrayVarName+$indexValue")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
|
||||
@ -127,7 +127,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
in ByteDatatypes -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||
asmgen.out(" lda $arrayVarName,y")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, true)
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||
@ -154,7 +154,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
fun assignViaExprEval(expression: PtExpression) {
|
||||
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
|
||||
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, true)
|
||||
}
|
||||
|
||||
val value = assign.source.memory!!
|
||||
@ -169,7 +169,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
is PtBinaryExpression -> {
|
||||
val addrExpr = value.address as PtBinaryExpression
|
||||
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, true)
|
||||
} else {
|
||||
assignViaExprEval(value.address)
|
||||
}
|
||||
@ -223,9 +223,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else -> {
|
||||
// do NOT restore X register before assigning the result values first
|
||||
when (returnValue.first.registerOrPair) {
|
||||
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes)
|
||||
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes)
|
||||
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes)
|
||||
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes, true)
|
||||
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes, true)
|
||||
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes, true)
|
||||
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
|
||||
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
|
||||
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
|
||||
@ -261,7 +261,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
if(assign.target.register==null) {
|
||||
// still need to assign the result to the target variable/etc.
|
||||
when(returnDt) {
|
||||
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A, returnDt in SignedDatatypes) // function's byte result is in A
|
||||
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A, returnDt in SignedDatatypes, false) // function's byte result is in A
|
||||
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
|
||||
DataType.STR -> {
|
||||
when (assign.target.datatype) {
|
||||
@ -306,7 +306,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
|
||||
else -> throw AssemblyError("invalid prefix operator")
|
||||
}
|
||||
assignRegisterByte(assign.target, CpuRegister.A, signed)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, signed, false)
|
||||
} else {
|
||||
assignExpressionToRegister(value.value, RegisterOrPair.AY, signed)
|
||||
when(value.operator) {
|
||||
@ -376,7 +376,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
is PtContainmentCheck -> {
|
||||
containmentCheckIntoA(value)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, true)
|
||||
}
|
||||
is PtBinaryExpression -> {
|
||||
if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
||||
@ -415,7 +415,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
when(target.datatype) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(" lda cx16.${register.toString().lowercase()}L")
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
}
|
||||
in WordDatatypes -> assignRegisterpairWord(target, register)
|
||||
else -> throw AssemblyError("expected byte or word")
|
||||
@ -493,7 +493,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
if(target.register==RegisterOrPair.A)
|
||||
asmgen.out(" cmp #0") // fix the status register
|
||||
else
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
return true
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
@ -513,7 +513,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" pha")
|
||||
assignExpressionToRegister(expr.right, RegisterOrPair.Y, false)
|
||||
asmgen.out(" pla | jsr math.divmod_ub_asm")
|
||||
assignRegisterByte(target, CpuRegister.Y, false)
|
||||
assignRegisterByte(target, CpuRegister.Y, false, true)
|
||||
return true
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
@ -521,7 +521,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" pha")
|
||||
assignExpressionToRegister(expr.right, RegisterOrPair.Y, true)
|
||||
asmgen.out(" pla | jsr math.divmod_b_asm")
|
||||
assignRegisterByte(target, CpuRegister.Y, true)
|
||||
assignRegisterByte(target, CpuRegister.Y, true, true)
|
||||
return true
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
@ -549,7 +549,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" pha")
|
||||
assignExpressionToRegister(expr.right, RegisterOrPair.Y, expr.type in SignedDatatypes)
|
||||
asmgen.out(" pla | jsr math.multiply_bytes")
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
return true
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
@ -587,7 +587,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" jsr math.mul_byte_${value}")
|
||||
else
|
||||
asmgen.out(" ldy #$value | jsr math.multiply_bytes")
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
return true
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
@ -647,7 +647,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" jsr math.lsr_ubyte_A")
|
||||
else
|
||||
asmgen.out(" jsr math.asl_byte_A")
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
assignRegisterByte(target, CpuRegister.A, signed, true)
|
||||
return true
|
||||
} else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed)
|
||||
@ -682,7 +682,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
assignRegisterByte(target, CpuRegister.A, signed, true)
|
||||
return true
|
||||
}
|
||||
else -> {
|
||||
@ -691,7 +691,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
} else {
|
||||
asmgen.out(" lda #0")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, signed)
|
||||
assignRegisterByte(target, CpuRegister.A, signed, true)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -764,7 +764,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" clc | adc $symname")
|
||||
else
|
||||
asmgen.out(" sec | sbc $symname")
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||
return true
|
||||
}
|
||||
is PtNumber -> {
|
||||
@ -773,7 +773,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" clc | adc #${right.number.toHex()}")
|
||||
else
|
||||
asmgen.out(" sec | sbc #${right.number.toHex()}")
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||
return true
|
||||
}
|
||||
else -> {
|
||||
@ -804,7 +804,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else
|
||||
asmgen.out(" sec | sbc $arrayvarname,y")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||
} else {
|
||||
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", right.type)
|
||||
assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE)
|
||||
@ -812,7 +812,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
||||
else
|
||||
asmgen.out(" sec | sbc P8ZP_SCRATCH_B1")
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes)
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -1005,7 +1005,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
return true
|
||||
}
|
||||
else if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||
@ -1044,7 +1044,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else -> return false
|
||||
}
|
||||
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, true)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1558,7 +1558,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else -> return false
|
||||
}
|
||||
|
||||
assignRegisterByte(assign.target, CpuRegister.A, signed)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, signed, true)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1575,7 +1575,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
"^", "xor" -> asmgen.out(" eor $operand")
|
||||
else -> throw AssemblyError("invalid operator")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
}
|
||||
|
||||
private fun assignLogicalWithSimpleRightOperandWord(target: AsmAssignTarget, left: PtExpression, operator: String, right: PtExpression) {
|
||||
@ -1614,7 +1614,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
beq +
|
||||
lda #1
|
||||
+ eor #1""")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, false)
|
||||
return true
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
@ -1625,13 +1625,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
beq +
|
||||
lda #1
|
||||
+ eor #1""")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, false)
|
||||
return true
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||
asmgen.out(" jsr floats.SIGN | and #1 | eor #1")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, false)
|
||||
return true
|
||||
}
|
||||
else->{
|
||||
@ -1645,7 +1645,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE)
|
||||
asmgen.out(" beq + | lda #1")
|
||||
asmgen.out("+")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, false)
|
||||
return true
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
@ -1653,13 +1653,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
|
||||
asmgen.out(" beq + | lda #1")
|
||||
asmgen.out("+")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, false, false)
|
||||
return true
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||
asmgen.out(" jsr floats.SIGN")
|
||||
assignRegisterByte(assign.target, CpuRegister.A, true)
|
||||
assignRegisterByte(assign.target, CpuRegister.A, true, false)
|
||||
return true
|
||||
}
|
||||
else->{
|
||||
@ -1731,7 +1731,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
else -> throw AssemblyError("can't use Z or N flags as return 'values'")
|
||||
}
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
}
|
||||
|
||||
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) {
|
||||
@ -1840,7 +1840,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
RegisterOrPair.XY,
|
||||
in Cx16VirtualRegisters -> {
|
||||
assignExpressionToRegister(value, RegisterOrPair.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
return
|
||||
}
|
||||
else -> {}
|
||||
@ -2770,13 +2770,33 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister, signed: Boolean) {
|
||||
private fun extendToMSBofVirtualReg(cpuRegister: CpuRegister, vreg: String, signed: Boolean) {
|
||||
if(signed) {
|
||||
when(cpuRegister) {
|
||||
CpuRegister.A -> { }
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
asmgen.out("""
|
||||
ora #$7f
|
||||
bmi +
|
||||
lda #0
|
||||
+ sta $vreg+1""")
|
||||
} else {
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||
asmgen.out(" stz $vreg+1")
|
||||
else
|
||||
asmgen.out(" lda #0 | sta $vreg+1")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister, signed: Boolean, extendWord: Boolean) {
|
||||
val assignAsWord = target.datatype in WordDatatypes
|
||||
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.out(" st${register.name.lowercase()} ${target.asmVarname}")
|
||||
if(assignAsWord) {
|
||||
if(assignAsWord && extendWord) {
|
||||
if(target.datatype in SignedDatatypes) {
|
||||
if(register!=CpuRegister.A)
|
||||
asmgen.out(" t${register.name.lowercase()}a")
|
||||
@ -2801,7 +2821,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(assignAsWord)
|
||||
TODO("assign register byte as word into Array not yet supported")
|
||||
assignRegisterByteToArray(target, register)
|
||||
assignRegisterByteToByteArray(target, register)
|
||||
}
|
||||
TargetStorageKind.REGISTER -> {
|
||||
when(register) {
|
||||
@ -2810,6 +2830,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
RegisterOrPair.X -> { asmgen.out(" tax") }
|
||||
RegisterOrPair.Y -> { asmgen.out(" tay") }
|
||||
RegisterOrPair.AY -> {
|
||||
require(extendWord) {
|
||||
"no extend"
|
||||
}
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
@ -2821,6 +2844,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" ldy #0")
|
||||
}
|
||||
RegisterOrPair.AX -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
ldx #0
|
||||
@ -2832,6 +2856,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" ldx #0")
|
||||
}
|
||||
RegisterOrPair.XY -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
tax
|
||||
@ -2845,8 +2870,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||
in Cx16VirtualRegisters -> {
|
||||
// only assign a single byte to the virtual register's Lsb
|
||||
asmgen.out(" sta cx16.${target.register.toString().lowercase()}")
|
||||
val reg = "cx16.${target.register.toString().lowercase()}"
|
||||
asmgen.out(" sta $reg")
|
||||
if(extendWord)
|
||||
extendToMSBofVirtualReg(CpuRegister.A, reg, signed)
|
||||
}
|
||||
else -> throw AssemblyError("weird register")
|
||||
}
|
||||
@ -2855,6 +2882,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
RegisterOrPair.X -> { }
|
||||
RegisterOrPair.Y -> { asmgen.out(" txy") }
|
||||
RegisterOrPair.AY -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
txa
|
||||
@ -2867,6 +2895,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" txa | ldy #0")
|
||||
}
|
||||
RegisterOrPair.AX -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
txa
|
||||
@ -2879,6 +2908,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" txa | ldx #0")
|
||||
}
|
||||
RegisterOrPair.XY -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
@ -2891,8 +2921,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||
in Cx16VirtualRegisters -> {
|
||||
// only assign a single byte to the virtual register's Lsb
|
||||
asmgen.out(" stx cx16.${target.register.toString().lowercase()}")
|
||||
val reg = "cx16.${target.register.toString().lowercase()}"
|
||||
asmgen.out(" stx $reg")
|
||||
if(extendWord)
|
||||
extendToMSBofVirtualReg(CpuRegister.X, reg, signed)
|
||||
}
|
||||
else -> throw AssemblyError("weird register")
|
||||
}
|
||||
@ -2901,6 +2933,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
RegisterOrPair.X -> { asmgen.out(" tyx") }
|
||||
RegisterOrPair.Y -> { }
|
||||
RegisterOrPair.AY -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
tya
|
||||
@ -2913,6 +2946,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" tya | ldy #0")
|
||||
}
|
||||
RegisterOrPair.AX -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
tya
|
||||
@ -2925,6 +2959,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" tya | ldx #0")
|
||||
}
|
||||
RegisterOrPair.XY -> {
|
||||
require(extendWord)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
tya
|
||||
@ -2939,8 +2974,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||
in Cx16VirtualRegisters -> {
|
||||
// only assign a single byte to the virtual register's Lsb
|
||||
asmgen.out(" sty cx16.${target.register.toString().lowercase()}")
|
||||
val reg = "cx16.${target.register.toString().lowercase()}"
|
||||
asmgen.out(" sty $reg")
|
||||
if(extendWord)
|
||||
extendToMSBofVirtualReg(CpuRegister.Y, reg, signed)
|
||||
}
|
||||
else -> throw AssemblyError("weird register")
|
||||
}
|
||||
@ -2949,7 +2986,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignRegisterByteToArray(target: AsmAssignTarget, register: CpuRegister) {
|
||||
private fun assignRegisterByteToByteArray(target: AsmAssignTarget, register: CpuRegister) {
|
||||
if(target.array!!.splitWords)
|
||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||
|
||||
@ -3553,7 +3590,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.out(" lda ${address.toHex()}")
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
}
|
||||
TargetStorageKind.REGISTER -> when(target.register!!) {
|
||||
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
|
||||
@ -3587,7 +3624,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.loadByteFromPointerIntoA(identifier)
|
||||
assignRegisterByte(target, CpuRegister.A, false)
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
}
|
||||
TargetStorageKind.REGISTER -> {
|
||||
asmgen.loadByteFromPointerIntoA(identifier)
|
||||
|
@ -1,8 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix the parameter passing bug intruduced recently. Example: cx16.FB_cursor_position(math.rnd(), math.rnd())
|
||||
|
||||
- add a %zpallowed option to specify the range of zeropage register that can be used (intersect with the actual available zp registers ofcourse)
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
|
Loading…
Reference in New Issue
Block a user