mirror of
https://github.com/irmen/prog8.git
synced 2025-08-18 19:33:18 +00:00
fix byte to word sign extension error in certain cases
This commit is contained in:
@@ -483,7 +483,7 @@ class AsmGen6502Internal (
|
|||||||
when(reg) {
|
when(reg) {
|
||||||
RegisterOrPair.A,
|
RegisterOrPair.A,
|
||||||
RegisterOrPair.X,
|
RegisterOrPair.X,
|
||||||
RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister())
|
RegisterOrPair.Y -> assignmentAsmGen.assignRegisterByte(target, reg.asCpuRegister(), false)
|
||||||
RegisterOrPair.AX,
|
RegisterOrPair.AX,
|
||||||
RegisterOrPair.AY,
|
RegisterOrPair.AY,
|
||||||
RegisterOrPair.XY,
|
RegisterOrPair.XY,
|
||||||
|
@@ -91,8 +91,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
val var3name = asmgen.asmVariableName(fcall.args[3] as PtIdentifier)
|
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 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)
|
val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[3].position, var3name)
|
||||||
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A)
|
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false)
|
||||||
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y)
|
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
|
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
|
||||||
@@ -304,7 +304,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" jsr prog8_lib.func_sqrt16_stack")
|
asmgen.out(" jsr prog8_lib.func_sqrt16_stack")
|
||||||
else {
|
else {
|
||||||
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
|
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
|
||||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A)
|
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +647,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A")
|
DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A")
|
||||||
else -> throw AssemblyError("weird type $dt")
|
else -> throw AssemblyError("weird type $dt")
|
||||||
}
|
}
|
||||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A)
|
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,7 +668,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${fcall.name}_f_into_A | ldy #0")
|
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${fcall.name}_f_into_A | ldy #0")
|
||||||
else -> throw AssemblyError("weird type $dt")
|
else -> throw AssemblyError("weird type $dt")
|
||||||
}
|
}
|
||||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A)
|
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,7 +75,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue")
|
asmgen.out(" lda $arrayVarName+$indexValue")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
|
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
|
||||||
@@ -104,7 +104,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y")
|
asmgen.out(" lda $arrayVarName,y")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
@@ -131,7 +131,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
fun assignViaExprEval(expression: PtExpression) {
|
fun assignViaExprEval(expression: PtExpression) {
|
||||||
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
|
assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD)
|
||||||
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
|
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val value = assign.source.memory!!
|
val value = assign.source.memory!!
|
||||||
@@ -147,7 +147,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
require(!asmgen.options.useNewExprCode)
|
require(!asmgen.options.useNewExprCode)
|
||||||
val addrExpr = value.address as PtBinaryExpression
|
val addrExpr = value.address as PtBinaryExpression
|
||||||
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
} else {
|
} else {
|
||||||
assignViaExprEval(value.address)
|
assignViaExprEval(value.address)
|
||||||
}
|
}
|
||||||
@@ -207,9 +207,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
else -> {
|
else -> {
|
||||||
// do NOT restore X register before assigning the result values first
|
// do NOT restore X register before assigning the result values first
|
||||||
when (returnValue.first.registerOrPair) {
|
when (returnValue.first.registerOrPair) {
|
||||||
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
|
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A, returnValue.second in SignedDatatypes)
|
||||||
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
|
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X, returnValue.second in SignedDatatypes)
|
||||||
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y)
|
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y, returnValue.second in SignedDatatypes)
|
||||||
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
|
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
|
||||||
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
|
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
|
||||||
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
|
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
|
||||||
@@ -247,7 +247,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(assign.target.register==null) {
|
if(assign.target.register==null) {
|
||||||
// still need to assign the result to the target variable/etc.
|
// still need to assign the result to the target variable/etc.
|
||||||
when(returnDt) {
|
when(returnDt) {
|
||||||
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A
|
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A, returnDt in SignedDatatypes) // function's byte result is in A
|
||||||
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
|
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
when (assign.target.datatype) {
|
when (assign.target.datatype) {
|
||||||
@@ -296,7 +296,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
is PtContainmentCheck -> {
|
is PtContainmentCheck -> {
|
||||||
containmentCheckIntoA(value)
|
containmentCheckIntoA(value)
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
require(!asmgen.options.useNewExprCode)
|
require(!asmgen.options.useNewExprCode)
|
||||||
@@ -337,7 +337,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
when(target.datatype) {
|
when(target.datatype) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.out(" lda cx16.${register.toString().lowercase()}L")
|
asmgen.out(" lda cx16.${register.toString().lowercase()}L")
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
assignRegisterByte(target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> assignRegisterpairWord(target, register)
|
in WordDatatypes -> assignRegisterpairWord(target, register)
|
||||||
else -> throw AssemblyError("expected byte or word")
|
else -> throw AssemblyError("expected byte or word")
|
||||||
@@ -398,7 +398,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
||||||
else -> throw AssemblyError("invalid operator")
|
else -> throw AssemblyError("invalid operator")
|
||||||
}
|
}
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
} else if(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes &&
|
} else if(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes &&
|
||||||
expr.left.isSimple() && expr.right.isSimple()) {
|
expr.left.isSimple() && expr.right.isSimple()) {
|
||||||
@@ -495,7 +495,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ lda #1
|
+ lda #1
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -513,7 +513,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" clc | adc $symname")
|
asmgen.out(" clc | adc $symname")
|
||||||
else
|
else
|
||||||
asmgen.out(" sec | sbc $symname")
|
asmgen.out(" sec | sbc $symname")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, dt in SignedDatatypes)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
is PtNumber -> {
|
is PtNumber -> {
|
||||||
@@ -522,7 +522,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" clc | adc #${right.number.toHex()}")
|
asmgen.out(" clc | adc #${right.number.toHex()}")
|
||||||
else
|
else
|
||||||
asmgen.out(" sec | sbc #${right.number.toHex()}")
|
asmgen.out(" sec | sbc #${right.number.toHex()}")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, dt in SignedDatatypes)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
@@ -650,7 +650,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, signed)
|
||||||
return true
|
return true
|
||||||
} else if(dt in WordDatatypes && shifts in 0..7) {
|
} else if(dt in WordDatatypes && shifts in 0..7) {
|
||||||
val signed = dt == DataType.WORD
|
val signed = dt == DataType.WORD
|
||||||
@@ -698,7 +698,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
"^", "xor" -> asmgen.out(" eor $operand")
|
"^", "xor" -> asmgen.out(" eor $operand")
|
||||||
else -> throw AssemblyError("invalid operator")
|
else -> throw AssemblyError("invalid operator")
|
||||||
}
|
}
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
assignRegisterByte(target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignLogicalWithSimpleRightOperandWord(target: AsmAssignTarget, left: PtExpression, operator: String, right: PtExpression) {
|
private fun assignLogicalWithSimpleRightOperandWord(target: AsmAssignTarget, left: PtExpression, operator: String, right: PtExpression) {
|
||||||
@@ -740,7 +740,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+""")
|
+""")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
@@ -753,13 +753,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+""")
|
+""")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||||
asmgen.out(" jsr floats.SIGN | and #1 | eor #1")
|
asmgen.out(" jsr floats.SIGN | and #1 | eor #1")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else->{
|
else->{
|
||||||
@@ -773,7 +773,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE)
|
assignExpressionToRegister(expr.left, RegisterOrPair.A, dt==DataType.BYTE)
|
||||||
asmgen.out(" beq + | lda #1")
|
asmgen.out(" beq + | lda #1")
|
||||||
asmgen.out("+")
|
asmgen.out("+")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
@@ -781,13 +781,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
|
asmgen.out(" sty P8ZP_SCRATCH_B1 | ora P8ZP_SCRATCH_B1")
|
||||||
asmgen.out(" beq + | lda #1")
|
asmgen.out(" beq + | lda #1")
|
||||||
asmgen.out("+")
|
asmgen.out("+")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
|
||||||
asmgen.out(" jsr floats.SIGN")
|
asmgen.out(" jsr floats.SIGN")
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A, true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else->{
|
else->{
|
||||||
@@ -868,7 +868,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
else -> throw AssemblyError("can't use Z or N flags as return 'values'")
|
else -> throw AssemblyError("can't use Z or N flags as return 'values'")
|
||||||
}
|
}
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
assignRegisterByte(target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) {
|
private fun assignTypeCastedValue(target: AsmAssignTarget, targetDt: DataType, value: PtExpression, origTypeCastExpression: PtTypeCast) {
|
||||||
@@ -2057,7 +2057,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) {
|
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister, signed: Boolean) {
|
||||||
// we make an exception in the type check for assigning something to a register pair AX, AY or XY
|
// we make an exception in the type check for assigning something to a register pair AX, AY or XY
|
||||||
// these will be correctly typecasted from a byte to a word value here
|
// these will be correctly typecasted from a byte to a word value here
|
||||||
if(target.register !in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY))
|
if(target.register !in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY))
|
||||||
@@ -2099,9 +2099,40 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
RegisterOrPair.A -> {}
|
RegisterOrPair.A -> {}
|
||||||
RegisterOrPair.X -> { asmgen.out(" tax") }
|
RegisterOrPair.X -> { asmgen.out(" tax") }
|
||||||
RegisterOrPair.Y -> { asmgen.out(" tay") }
|
RegisterOrPair.Y -> { asmgen.out(" tay") }
|
||||||
RegisterOrPair.AY -> { asmgen.out(" ldy #0") }
|
RegisterOrPair.AY -> {
|
||||||
RegisterOrPair.AX -> { asmgen.out(" ldx #0") }
|
if(signed)
|
||||||
RegisterOrPair.XY -> { asmgen.out(" tax | ldy #0") }
|
asmgen.out("""
|
||||||
|
ldy #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" ldy #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.AX -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
ldx #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dex
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" ldx #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.XY -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
tax
|
||||||
|
ldy #0
|
||||||
|
cpx #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" tax | ldy #0")
|
||||||
|
}
|
||||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||||
in Cx16VirtualRegisters -> {
|
in Cx16VirtualRegisters -> {
|
||||||
// only assign a single byte to the virtual register's Lsb
|
// only assign a single byte to the virtual register's Lsb
|
||||||
@@ -2113,9 +2144,41 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
RegisterOrPair.A -> { asmgen.out(" txa") }
|
RegisterOrPair.A -> { asmgen.out(" txa") }
|
||||||
RegisterOrPair.X -> { }
|
RegisterOrPair.X -> { }
|
||||||
RegisterOrPair.Y -> { asmgen.out(" txy") }
|
RegisterOrPair.Y -> { asmgen.out(" txy") }
|
||||||
RegisterOrPair.AY -> { asmgen.out(" txa | ldy #0") }
|
RegisterOrPair.AY -> {
|
||||||
RegisterOrPair.AX -> { asmgen.out(" txa | ldx #0") }
|
if(signed)
|
||||||
RegisterOrPair.XY -> { asmgen.out(" ldy #0") }
|
asmgen.out("""
|
||||||
|
txa
|
||||||
|
ldy #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" txa | ldy #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.AX -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
txa
|
||||||
|
ldx #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dex
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" txa | ldx #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.XY -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #0
|
||||||
|
cpx #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" ldy #0")
|
||||||
|
}
|
||||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||||
in Cx16VirtualRegisters -> {
|
in Cx16VirtualRegisters -> {
|
||||||
// only assign a single byte to the virtual register's Lsb
|
// only assign a single byte to the virtual register's Lsb
|
||||||
@@ -2127,9 +2190,43 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
RegisterOrPair.A -> { asmgen.out(" tya") }
|
RegisterOrPair.A -> { asmgen.out(" tya") }
|
||||||
RegisterOrPair.X -> { asmgen.out(" tyx") }
|
RegisterOrPair.X -> { asmgen.out(" tyx") }
|
||||||
RegisterOrPair.Y -> { }
|
RegisterOrPair.Y -> { }
|
||||||
RegisterOrPair.AY -> { asmgen.out(" tya | ldy #0") }
|
RegisterOrPair.AY -> {
|
||||||
RegisterOrPair.AX -> { asmgen.out(" tya | ldx #0") }
|
if(signed)
|
||||||
RegisterOrPair.XY -> { asmgen.out(" tya | tax | ldy #0") }
|
asmgen.out("""
|
||||||
|
tya
|
||||||
|
ldy #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" tya | ldy #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.AX -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
tya
|
||||||
|
ldx #0
|
||||||
|
cmp #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dex
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" tya | ldx #0")
|
||||||
|
}
|
||||||
|
RegisterOrPair.XY -> {
|
||||||
|
if(signed)
|
||||||
|
asmgen.out("""
|
||||||
|
tya
|
||||||
|
tax
|
||||||
|
ldy #0
|
||||||
|
cpx #${'$'}80
|
||||||
|
bcc +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out(" tya | tax | ldy #0")
|
||||||
|
}
|
||||||
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected type cast to float")
|
||||||
in Cx16VirtualRegisters -> {
|
in Cx16VirtualRegisters -> {
|
||||||
// only assign a single byte to the virtual register's Lsb
|
// only assign a single byte to the virtual register's Lsb
|
||||||
@@ -2666,7 +2763,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
asmgen.out(" lda ${address.toHex()}")
|
asmgen.out(" lda ${address.toHex()}")
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
assignRegisterByte(target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> when(target.register!!) {
|
TargetStorageKind.REGISTER -> when(target.register!!) {
|
||||||
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
|
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
|
||||||
@@ -2706,7 +2803,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
asmgen.loadByteFromPointerIntoA(identifier)
|
asmgen.loadByteFromPointerIntoA(identifier)
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
assignRegisterByte(target, CpuRegister.A, false)
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> {
|
TargetStorageKind.REGISTER -> {
|
||||||
asmgen.loadByteFromPointerIntoA(identifier)
|
asmgen.loadByteFromPointerIntoA(identifier)
|
||||||
|
@@ -1,9 +1,28 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%option no_sysinit
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
sys.set_leds_brightness(255, 255)
|
byte v1s = 22
|
||||||
sys.wait(120)
|
byte v2s = -99
|
||||||
sys.reset_system()
|
word ww
|
||||||
|
|
||||||
|
txt.print_w(minsb()) ; TODO WRONG RESULT!
|
||||||
|
txt.spc()
|
||||||
|
ww = minsb()
|
||||||
|
txt.print_w(ww)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_b(minsb())
|
||||||
|
txt.spc()
|
||||||
|
v2s = minsb()
|
||||||
|
txt.print_w(v2s)
|
||||||
|
|
||||||
|
sub minsb() -> byte {
|
||||||
|
cx16.r0++
|
||||||
|
return v2s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user