mirror of
https://github.com/irmen/prog8.git
synced 2024-07-08 10:29:09 +00:00
asm fix
This commit is contained in:
parent
c83a61c460
commit
ef7744dbda
@ -52,6 +52,7 @@ multiply_words .proc
|
|||||||
; -- multiply two 16-bit words into a 32-bit result (signed and unsigned)
|
; -- multiply two 16-bit words into a 32-bit result (signed and unsigned)
|
||||||
; input: A/Y = first 16-bit number, c64.SCRATCH_ZPWORD1 in ZP = second 16-bit number
|
; input: A/Y = first 16-bit number, c64.SCRATCH_ZPWORD1 in ZP = second 16-bit number
|
||||||
; output: multiply_words.result 4-bytes/32-bits product, LSB order (low-to-high)
|
; output: multiply_words.result 4-bytes/32-bits product, LSB order (low-to-high)
|
||||||
|
; clobbers: A
|
||||||
|
|
||||||
sta c64.SCRATCH_ZPWORD2
|
sta c64.SCRATCH_ZPWORD2
|
||||||
sty c64.SCRATCH_ZPWORD2+1
|
sty c64.SCRATCH_ZPWORD2+1
|
||||||
|
@ -55,7 +55,7 @@ write_byte_to_address_on_stack .proc
|
|||||||
ldy c64.ESTACK_HI+1,x
|
ldy c64.ESTACK_HI+1,x
|
||||||
sty c64.SCRATCH_ZPWORD2+1
|
sty c64.SCRATCH_ZPWORD2+1
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (c64.SCRATCH_ZPWORD2),y
|
sta (c64.SCRATCH_ZPWORD2),y
|
||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
@ -343,9 +343,7 @@ mul_word .proc
|
|||||||
sta c64.SCRATCH_ZPWORD1+1
|
sta c64.SCRATCH_ZPWORD1+1
|
||||||
lda c64.ESTACK_LO+1,x
|
lda c64.ESTACK_LO+1,x
|
||||||
ldy c64.ESTACK_HI+1,x
|
ldy c64.ESTACK_HI+1,x
|
||||||
stx c64.SCRATCH_ZPREGX
|
|
||||||
jsr math.multiply_words
|
jsr math.multiply_words
|
||||||
ldx c64.SCRATCH_ZPREGX
|
|
||||||
lda math.multiply_words.result
|
lda math.multiply_words.result
|
||||||
sta c64.ESTACK_LO+1,x
|
sta c64.ESTACK_LO+1,x
|
||||||
lda math.multiply_words.result+1
|
lda math.multiply_words.result+1
|
||||||
|
@ -371,29 +371,31 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val addressExpr = memoryAddress.addressExpression
|
val addressExpr = memoryAddress.addressExpression
|
||||||
val addressLv = addressExpr as? NumericLiteralValue
|
val addressLv = addressExpr as? NumericLiteralValue
|
||||||
when {
|
when {
|
||||||
addressLv != null -> asmgen.out(" lda $ldaInstructionArg | sta ${addressLv.number.toHex()}")
|
addressLv != null -> {
|
||||||
|
asmgen.out(" lda $ldaInstructionArg | sta ${addressLv.number.toHex()}")
|
||||||
|
}
|
||||||
addressExpr is IdentifierReference -> {
|
addressExpr is IdentifierReference -> {
|
||||||
val pointerVarName = asmgen.asmIdentifierName(addressExpr)
|
val pointerVarName = asmgen.asmIdentifierName(addressExpr)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $pointerVarName
|
lda $pointerVarName
|
||||||
sta ${C64Zeropage.SCRATCH_W2}
|
sta ${C64Zeropage.SCRATCH_W2}
|
||||||
lda $pointerVarName+1
|
lda $pointerVarName+1
|
||||||
sta ${C64Zeropage.SCRATCH_W2+1}
|
sta ${C64Zeropage.SCRATCH_W2+1}
|
||||||
lda $ldaInstructionArg
|
lda $ldaInstructionArg
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.translateExpression(addressExpr)
|
asmgen.translateExpression(addressExpr)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda $ESTACK_LO_HEX,x
|
||||||
sta ${C64Zeropage.SCRATCH_W2}
|
sta ${C64Zeropage.SCRATCH_W2}
|
||||||
lda $ESTACK_HI_HEX,x
|
lda $ESTACK_HI_HEX,x
|
||||||
sta ${C64Zeropage.SCRATCH_W2+1}
|
sta ${C64Zeropage.SCRATCH_W2+1}
|
||||||
lda $ldaInstructionArg
|
lda $ldaInstructionArg
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +406,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val addressLv = addressExpr as? NumericLiteralValue
|
val addressLv = addressExpr as? NumericLiteralValue
|
||||||
val registerName = register.name.toLowerCase()
|
val registerName = register.name.toLowerCase()
|
||||||
when {
|
when {
|
||||||
addressLv != null -> asmgen.out(" st$registerName ${addressLv.number.toHex()}")
|
addressLv != null -> {
|
||||||
|
asmgen.out(" st$registerName ${addressLv.number.toHex()}")
|
||||||
|
}
|
||||||
addressExpr is IdentifierReference -> {
|
addressExpr is IdentifierReference -> {
|
||||||
val targetName = asmgen.asmIdentifierName(addressExpr)
|
val targetName = asmgen.asmIdentifierName(addressExpr)
|
||||||
when (register) {
|
when (register) {
|
||||||
@ -413,25 +417,25 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
CpuRegister.Y -> asmgen.out(" tya")
|
CpuRegister.Y -> asmgen.out(" tya")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $targetName
|
ldy $targetName
|
||||||
sty ${C64Zeropage.SCRATCH_W1}
|
sty ${C64Zeropage.SCRATCH_W1}
|
||||||
ldy $targetName+1
|
ldy $targetName+1
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.saveRegister(register)
|
asmgen.saveRegister(register)
|
||||||
asmgen.translateExpression(addressExpr)
|
asmgen.translateExpression(addressExpr)
|
||||||
asmgen.restoreRegister(CpuRegister.A)
|
asmgen.restoreRegister(CpuRegister.A)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
ldy $ESTACK_LO_HEX,x
|
ldy $ESTACK_LO_HEX,x
|
||||||
sty ${C64Zeropage.SCRATCH_W1}
|
sty ${C64Zeropage.SCRATCH_W1}
|
||||||
ldy $ESTACK_HI_HEX,x
|
ldy $ESTACK_HI_HEX,x
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
|
|
||||||
internal class AugmentableAssignmentAsmGen(private val program: Program,
|
internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||||
private val assignmentAsmGen: AssignmentAsmGen,
|
private val assignmentAsmGen: AssignmentAsmGen,
|
||||||
private val asmgen: AsmGen) {
|
private val asmgen: AsmGen) {
|
||||||
fun translate(assign: Assignment) {
|
fun translate(assign: Assignment) {
|
||||||
require(assign.isAugmentable)
|
require(assign.isAugmentable)
|
||||||
|
|
||||||
@ -22,8 +22,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// A = -A , A = +A, A = ~A
|
// A = -A , A = +A, A = ~A
|
||||||
val px = assign.value as PrefixExpression
|
val px = assign.value as PrefixExpression
|
||||||
val type = px.inferType(program).typeOrElse(DataType.STRUCT)
|
val type = px.inferType(program).typeOrElse(DataType.STRUCT)
|
||||||
when(px.operator) {
|
when (px.operator) {
|
||||||
"+" -> {}
|
"+" -> {
|
||||||
|
}
|
||||||
"-" -> inplaceNegate(assign.target, type)
|
"-" -> inplaceNegate(assign.target, type)
|
||||||
"~" -> inplaceInvert(assign.target, type)
|
"~" -> inplaceInvert(assign.target, type)
|
||||||
"not" -> inplaceBooleanNot(assign.target, type)
|
"not" -> inplaceBooleanNot(assign.target, type)
|
||||||
@ -43,10 +44,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
return inplaceModification(target, binExpr.operator, binExpr.right, assign)
|
return inplaceModification(target, binExpr.operator, binExpr.right, assign)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binExpr.operator in associativeOperators)
|
if (binExpr.operator in associativeOperators) {
|
||||||
{
|
|
||||||
val leftBinExpr = binExpr.left as? BinaryExpression
|
val leftBinExpr = binExpr.left as? BinaryExpression
|
||||||
if (leftBinExpr!=null && binExpr.right isSameAs target) {
|
if (leftBinExpr != null && binExpr.right isSameAs target) {
|
||||||
// A = 5 <operator> A
|
// A = 5 <operator> A
|
||||||
return inplaceModification(target, binExpr.operator, binExpr.left, assign)
|
return inplaceModification(target, binExpr.operator, binExpr.left, assign)
|
||||||
}
|
}
|
||||||
@ -110,30 +110,30 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
val ident = value as? IdentifierReference
|
val ident = value as? IdentifierReference
|
||||||
|
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
val dt = identifier.inferType(program).typeOrElse(DataType.STRUCT)
|
val dt = identifier.inferType(program).typeOrElse(DataType.STRUCT)
|
||||||
when (dt) {
|
when (dt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_byte_litval_to_variable(name, operator, valueLv)
|
valueLv != null -> inplaceModification_byte_litval_to_variable(name, dt, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_byte_variable_to_variable(name, operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_variable(name, dt, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_byte_value_to_variable(name, operator, value)
|
else -> inplaceModification_byte_value_to_variable(name, dt, operator, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_word_litval_to_variable(name, operator, valueLv)
|
valueLv != null -> inplaceModification_word_litval_to_variable(name, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_word_variable_to_variable(name, operator, ident)
|
ident != null -> inplaceModification_word_variable_to_variable(name, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_word_value_to_variable(name, operator, value)
|
else -> inplaceModification_word_value_to_variable(name, operator, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_float_litval_to_variable(name, operator, valueLv)
|
valueLv != null -> inplaceModification_float_litval_to_variable(name, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_float_variable_to_variable(name, operator, ident)
|
ident != null -> inplaceModification_float_variable_to_variable(name, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_float_value_to_variable(name, operator, value)
|
else -> inplaceModification_float_value_to_variable(name, operator, value)
|
||||||
}
|
}
|
||||||
@ -144,23 +144,23 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memory!=null -> {
|
memory != null -> {
|
||||||
when (memory.addressExpression) {
|
when (memory.addressExpression) {
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
val addr = (memory.addressExpression as NumericLiteralValue).number.toInt()
|
val addr = (memory.addressExpression as NumericLiteralValue).number.toInt()
|
||||||
// re-use code to assign a variable, instead this time, use a direct memory address
|
// re-use code to assign a variable, instead this time, use a direct memory address
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_byte_litval_to_variable(addr.toHex(), operator, valueLv)
|
valueLv != null -> inplaceModification_byte_litval_to_variable(addr.toHex(), DataType.UBYTE, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_byte_variable_to_variable(addr.toHex(), operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_variable(addr.toHex(), DataType.UBYTE, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_byte_value_to_variable(addr.toHex(), operator, value)
|
else -> inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val name = asmgen.asmIdentifierName(memory.addressExpression as IdentifierReference)
|
val name = asmgen.asmIdentifierName(memory.addressExpression as IdentifierReference)
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_byte_litval_to_memory(name, operator, valueLv)
|
valueLv != null -> inplaceModification_byte_litval_to_memory(name, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_byte_variable_to_memory(name, operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_memory(name, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_byte_value_to_memory(name, operator, value, origAssign)
|
else -> inplaceModification_byte_value_to_memory(name, operator, value, origAssign)
|
||||||
}
|
}
|
||||||
@ -170,16 +170,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta ${C64Zeropage.SCRATCH_B1}")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta ${C64Zeropage.SCRATCH_B1}")
|
||||||
// the original memory byte's value is now in the scratch B1 location.
|
// the original memory byte's value is now in the scratch B1 location.
|
||||||
when {
|
when {
|
||||||
valueLv!=null -> inplaceModification_byte_litval_to_variable(C64Zeropage.SCRATCH_B1.toHex(), operator, valueLv)
|
valueLv != null -> inplaceModification_byte_litval_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, valueLv)
|
||||||
ident!=null -> inplaceModification_byte_variable_to_variable(C64Zeropage.SCRATCH_B1.toHex(), operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
else -> inplaceModification_byte_value_to_variable(C64Zeropage.SCRATCH_B1.toHex(), operator, value)
|
else -> inplaceModification_byte_value_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
||||||
}
|
}
|
||||||
asmgen.out(" lda ${C64Zeropage.SCRATCH_B1} | jsr prog8_lib.write_byte_to_address_on_stack | inx")
|
asmgen.out(" lda ${C64Zeropage.SCRATCH_B1} | jsr prog8_lib.write_byte_to_address_on_stack | inx")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arrayIdx!=null -> {
|
arrayIdx != null -> {
|
||||||
println("TODO 3 optimize simple inplace array assignment $arrayIdx $operator= $value")
|
println("TODO 3 optimize simple inplace array assignment $arrayIdx $operator= $value")
|
||||||
assignmentAsmGen.translateOtherAssignment(origAssign) // TODO get rid of this fallback
|
assignmentAsmGen.translateOtherAssignment(origAssign) // TODO get rid of this fallback
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// this should be the last resort for code generation for this,
|
// this should be the last resort for code generation for this,
|
||||||
// because the value is evaluated onto the eval stack (=slow).
|
// because the value is evaluated onto the eval stack (=slow).
|
||||||
asmgen.translateExpression(value)
|
asmgen.translateExpression(value)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
"**" -> TODO("pow")
|
"**" -> TODO("pow")
|
||||||
"+" -> {
|
"+" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -207,7 +207,18 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
TODO("-")
|
asmgen.out("""
|
||||||
|
jsr c64flt.pop_float_fac1
|
||||||
|
stx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr c64flt.CONUPK
|
||||||
|
jsr c64flt.FSUBT
|
||||||
|
ldx #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr c64flt.MOVMF
|
||||||
|
ldx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> {
|
"/" -> {
|
||||||
@ -231,10 +242,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
||||||
val constValueName = asmgen.getFloatConst(value)
|
val constValueName = asmgen.getFloatConst(value)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
"**" -> TODO("pow")
|
"**" -> TODO("pow")
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if(value==0.0)
|
if (value == 0.0)
|
||||||
return
|
return
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
@ -252,13 +263,26 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if(value==0.0)
|
if (value == 0.0)
|
||||||
return
|
return
|
||||||
TODO("-")
|
asmgen.out("""
|
||||||
|
stx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr c64flt.MOVFM
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr c64flt.CONUPK
|
||||||
|
jsr c64flt.FSUBT
|
||||||
|
ldx #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr c64flt.MOVMF
|
||||||
|
ldx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> {
|
"/" -> {
|
||||||
if(value==0.0)
|
if (value == 0.0)
|
||||||
throw AssemblyError("division by zero")
|
throw AssemblyError("division by zero")
|
||||||
TODO()
|
TODO()
|
||||||
// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
@ -275,7 +299,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun inplaceModification_byte_value_to_memory(pointername: String, operator: String, value: Expression, origAssign: Assignment) {
|
private fun inplaceModification_byte_value_to_memory(pointername: String, operator: String, value: Expression, origAssign: Assignment) {
|
||||||
assignmentAsmGen.translateOtherAssignment(origAssign) // TODO get rid of this fallback
|
assignmentAsmGen.translateOtherAssignment(origAssign) // TODO get rid of this fallback
|
||||||
TODO("Not yet implemented")
|
TODO("inplaceModification_byte_value_to_memory")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_variable_to_memory(pointername: String, operator: String, ident: IdentifierReference) {
|
private fun inplaceModification_byte_variable_to_memory(pointername: String, operator: String, ident: IdentifierReference) {
|
||||||
@ -285,11 +309,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
lda $pointername
|
lda $pointername
|
||||||
ldy $pointername+1
|
ldy $pointername+1
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (${C64Zeropage.SCRATCH_W1}),y""")
|
lda (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
loadByteFromPointerInA()
|
loadByteFromPointerInA()
|
||||||
@ -331,11 +355,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
lda $pointername
|
lda $pointername
|
||||||
ldy $pointername+1
|
ldy $pointername+1
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (${C64Zeropage.SCRATCH_W1}),y""")
|
lda (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
loadByteFromPointerInA()
|
loadByteFromPointerInA()
|
||||||
@ -354,14 +378,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
loadByteFromPointerInA()
|
loadByteFromPointerInA()
|
||||||
repeat(value.toInt()) { asmgen.out(" asl a") }
|
repeat(value.toInt()) { asmgen.out(" asl a") }
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
loadByteFromPointerInA()
|
loadByteFromPointerInA()
|
||||||
repeat(value.toInt()) { asmgen.out(" lsr a") }
|
repeat(value.toInt()) { asmgen.out(" lsr a") }
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
||||||
@ -384,27 +408,41 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_word_litval_to_variable(name: String, operator: String, value: Double) {
|
private fun inplaceModification_word_litval_to_variable(name: String, operator: String, value: Double) {
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc #<$value | sta $name | lda $name+1 | adc #>$value | sta $name+1")
|
"+" -> asmgen.out(" lda $name | clc | adc #<$value | sta $name | lda $name+1 | adc #>$value | sta $name+1")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc #<$value | sta $name | lda $name+1 | sbc #>$value | sta $name+1")
|
"-" -> asmgen.out(" lda $name | sec | sbc #<$value | sta $name | lda $name+1 | sbc #>$value | sta $name+1")
|
||||||
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> {
|
||||||
"/" -> TODO()// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
// TODO what about the optimized routines?
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
sta c64.SCRATCH_ZPWORD1
|
||||||
|
lda $name+1
|
||||||
|
sta c64.SCRATCH_ZPWORD1+1
|
||||||
|
lda #<$value
|
||||||
|
ldy #>$value
|
||||||
|
jsr math.multiply_words
|
||||||
|
lda math.multiply_words.result
|
||||||
|
sta $name
|
||||||
|
lda math.multiply_words.result+1
|
||||||
|
sta $name+1,x""")
|
||||||
|
}
|
||||||
|
"/" -> TODO("word $name /= $value")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
"%" -> {
|
"%" -> {
|
||||||
TODO("word remainder")
|
TODO("word remainder $value")
|
||||||
// if(types==DataType.BYTE)
|
// if(types==DataType.BYTE)
|
||||||
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||||
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
asmgen.out(" lda $name")
|
asmgen.out(" lda $name")
|
||||||
TODO("word asl")
|
TODO("word asl")
|
||||||
asmgen.out(" sta $name")
|
asmgen.out(" sta $name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
asmgen.out(" lda $name")
|
asmgen.out(" lda $name")
|
||||||
TODO("word lsr")
|
TODO("word lsr")
|
||||||
asmgen.out(" sta $name")
|
asmgen.out(" sta $name")
|
||||||
@ -419,7 +457,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun inplaceModification_word_variable_to_variable(name: String, operator: String, ident: IdentifierReference) {
|
private fun inplaceModification_word_variable_to_variable(name: String, operator: String, ident: IdentifierReference) {
|
||||||
val otherName = asmgen.asmIdentifierName(ident)
|
val otherName = asmgen.asmIdentifierName(ident)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name | lda $name+1 | adc $otherName+1 | sta $name+1")
|
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name | lda $name+1 | adc $otherName+1 | sta $name+1")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name | lda $name+1 | sbc $otherName+1 | sta $name+1")
|
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name | lda $name+1 | sbc $otherName+1 | sta $name+1")
|
||||||
@ -444,7 +482,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// this should be the last resort for code generation for this,
|
// this should be the last resort for code generation for this,
|
||||||
// because the value is evaluated onto the eval stack (=slow).
|
// because the value is evaluated onto the eval stack (=slow).
|
||||||
asmgen.translateExpression(value)
|
asmgen.translateExpression(value)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | adc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | adc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | sbc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | sbc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
||||||
@ -466,11 +504,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" inx")
|
asmgen.out(" inx")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_value_to_variable(name: String, operator: String, value: Expression) {
|
private fun inplaceModification_byte_value_to_variable(name: String, dt: DataType, operator: String, value: Expression) {
|
||||||
// this should be the last resort for code generation for this,
|
// this should be the last resort for code generation for this,
|
||||||
// because the value is evaluated onto the eval stack (=slow).
|
// because the value is evaluated onto the eval stack (=slow).
|
||||||
asmgen.translateExpression(value)
|
asmgen.translateExpression(value)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
||||||
@ -492,9 +530,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" inx")
|
asmgen.out(" inx")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_variable_to_variable(name: String, operator: String, ident: IdentifierReference) {
|
private fun inplaceModification_byte_variable_to_variable(name: String, dt: DataType, operator: String, ident: IdentifierReference) {
|
||||||
val otherName = asmgen.asmIdentifierName(ident)
|
val otherName = asmgen.asmIdentifierName(ident)
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name")
|
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name")
|
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name")
|
||||||
@ -515,28 +553,45 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_litval_to_variable(name: String, operator: String, value: Double) {
|
private fun inplaceModification_byte_litval_to_variable(name: String, dt: DataType, operator: String, value: Double) {
|
||||||
when(operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc #$value | sta $name")
|
"+" -> asmgen.out(" lda $name | clc | adc #$value | sta $name")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc #$value | sta $name")
|
"-" -> asmgen.out(" lda $name | sec | sbc #$value | sta $name")
|
||||||
"*" -> TODO()// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> {
|
||||||
"/" -> TODO()// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
// TODO what about the optimized routines?
|
||||||
|
TODO("$dt mul $name *= $value")
|
||||||
|
// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
|
}
|
||||||
|
"/" -> {
|
||||||
|
if (dt == DataType.UBYTE) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
ldy #$value
|
||||||
|
jsr math.divmod_ub
|
||||||
|
sty $name
|
||||||
|
""")
|
||||||
|
} else {
|
||||||
|
// BYTE
|
||||||
|
// requires to use unsigned division and fix sign afterwards, see idiv_b in prog8lib
|
||||||
|
TODO("BYTE div $name /= $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
TODO("byte remainder")
|
TODO("$dt remainder")
|
||||||
// if(types==DataType.BYTE)
|
// if(types==DataType.BYTE)
|
||||||
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
// throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||||
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
asmgen.out(" lda $name")
|
asmgen.out(" lda $name")
|
||||||
repeat(value.toInt()) { asmgen.out(" asl a") }
|
repeat(value.toInt()) { asmgen.out(" asl a") }
|
||||||
asmgen.out(" sta $name")
|
asmgen.out(" sta $name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if(value>1) {
|
if (value > 1) {
|
||||||
asmgen.out(" lda $name")
|
asmgen.out(" lda $name")
|
||||||
repeat(value.toInt()) { asmgen.out(" lsr a") }
|
repeat(value.toInt()) { asmgen.out(" lsr a") }
|
||||||
asmgen.out(" sta $name")
|
asmgen.out(" sta $name")
|
||||||
@ -554,26 +609,28 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
val outerCastDt = cast.type
|
val outerCastDt = cast.type
|
||||||
val innerCastDt = (cast.expression as? TypecastExpression)?.type
|
val innerCastDt = (cast.expression as? TypecastExpression)?.type
|
||||||
|
|
||||||
if(innerCastDt==null) {
|
if (innerCastDt == null) {
|
||||||
// simple typecast where the value is the target
|
// simple typecast where the value is the target
|
||||||
when(targetDt) {
|
when (targetDt) {
|
||||||
DataType.UBYTE, DataType.BYTE -> { /* byte target can't be casted to anything else at all */ }
|
DataType.UBYTE, DataType.BYTE -> { /* byte target can't be casted to anything else at all */
|
||||||
|
}
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
when(outerCastDt) {
|
when (outerCastDt) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
if(target.identifier!=null) {
|
if (target.identifier != null) {
|
||||||
val name = asmgen.asmIdentifierName(target.identifier!!)
|
val name = asmgen.asmIdentifierName(target.identifier!!)
|
||||||
asmgen.out(" lda #0 | sta $name+1")
|
asmgen.out(" lda #0 | sta $name+1")
|
||||||
} else
|
} else
|
||||||
throw AssemblyError("weird value")
|
throw AssemblyError("weird value")
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD, in IterableDatatypes -> {}
|
DataType.UWORD, DataType.WORD, in IterableDatatypes -> {
|
||||||
|
}
|
||||||
DataType.FLOAT -> throw AssemblyError("incompatible cast type")
|
DataType.FLOAT -> throw AssemblyError("incompatible cast type")
|
||||||
else -> throw AssemblyError("weird cast type")
|
else -> throw AssemblyError("weird cast type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
if(outerCastDt!=DataType.FLOAT)
|
if (outerCastDt != DataType.FLOAT)
|
||||||
throw AssemblyError("in-place cast of a float makes no sense")
|
throw AssemblyError("in-place cast of a float makes no sense")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid cast target type")
|
else -> throw AssemblyError("invalid cast target type")
|
||||||
@ -581,19 +638,19 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
// typecast with nested typecast, that has the target as a value
|
// typecast with nested typecast, that has the target as a value
|
||||||
// calculate singular cast that is required
|
// calculate singular cast that is required
|
||||||
val castDt = if(outerCastDt largerThan innerCastDt) innerCastDt else outerCastDt
|
val castDt = if (outerCastDt largerThan innerCastDt) innerCastDt else outerCastDt
|
||||||
val value = (cast.expression as TypecastExpression).expression
|
val value = (cast.expression as TypecastExpression).expression
|
||||||
val resultingCast = TypecastExpression(value, castDt, false, assign.position)
|
val resultingCast = TypecastExpression(value, castDt, false, assign.position)
|
||||||
inplaceCast(target, resultingCast, assign)
|
inplaceCast(target, resultingCast, assign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceBooleanNot(target: AssignTarget, dt: DataType) {
|
private fun inplaceBooleanNot(target: AssignTarget, dt: DataType) {
|
||||||
val arrayIdx = target.arrayindexed
|
val arrayIdx = target.arrayindexed
|
||||||
val identifier = target.identifier
|
val identifier = target.identifier
|
||||||
val memory = target.memoryAddress
|
val memory = target.memoryAddress
|
||||||
|
|
||||||
when(dt) {
|
when (dt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when {
|
when {
|
||||||
identifier != null -> {
|
identifier != null -> {
|
||||||
@ -631,7 +688,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
TODO("$memory")
|
asmgen.translateExpression(memory.addressExpression)
|
||||||
|
asmgen.out("""
|
||||||
|
jsr prog8_lib.read_byte_from_address_on_stack
|
||||||
|
beq +
|
||||||
|
lda #1
|
||||||
|
+ eor #1
|
||||||
|
jsr prog8_lib.write_byte_to_address_on_stack
|
||||||
|
inx""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,7 +706,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
@ -654,8 +718,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
lsr a
|
lsr a
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
}
|
}
|
||||||
arrayIdx!=null -> TODO("in-place not of uword array")
|
arrayIdx != null -> TODO("in-place not of uword array")
|
||||||
memory!=null -> throw AssemblyError("no asm gen for uword-memory not")
|
memory != null -> throw AssemblyError("no asm gen for uword-memory not")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("boolean-not of invalid type")
|
else -> throw AssemblyError("boolean-not of invalid type")
|
||||||
@ -667,7 +731,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
val identifier = target.identifier
|
val identifier = target.identifier
|
||||||
val memory = target.memoryAddress
|
val memory = target.memoryAddress
|
||||||
|
|
||||||
when(dt) {
|
when (dt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when {
|
when {
|
||||||
identifier != null -> {
|
identifier != null -> {
|
||||||
@ -699,7 +763,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
sta (${C64Zeropage.SCRATCH_W1}),y""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
TODO("$memory")
|
asmgen.translateExpression(memory.addressExpression)
|
||||||
|
asmgen.out("""
|
||||||
|
jsr prog8_lib.read_byte_from_address_on_stack
|
||||||
|
eor #255
|
||||||
|
jsr prog8_lib.write_byte_to_address_on_stack
|
||||||
|
inx""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,7 +779,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
@ -720,8 +789,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
eor #255
|
eor #255
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
}
|
}
|
||||||
arrayIdx!=null -> TODO("in-place invert uword array")
|
arrayIdx != null -> TODO("in-place invert uword array")
|
||||||
memory!=null -> throw AssemblyError("no asm gen for uword-memory invert")
|
memory != null -> throw AssemblyError("no asm gen for uword-memory invert")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invert of invalid type")
|
else -> throw AssemblyError("invert of invalid type")
|
||||||
@ -733,10 +802,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
val identifier = target.identifier
|
val identifier = target.identifier
|
||||||
val memory = target.memoryAddress
|
val memory = target.memoryAddress
|
||||||
|
|
||||||
when(dt) {
|
when (dt) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #0
|
lda #0
|
||||||
@ -744,13 +813,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sbc $name
|
sbc $name
|
||||||
sta $name""")
|
sta $name""")
|
||||||
}
|
}
|
||||||
memory!=null -> throw AssemblyError("can't in-place negate memory ubyte")
|
memory != null -> throw AssemblyError("can't in-place negate memory ubyte")
|
||||||
arrayIdx!=null -> TODO("in-place negate byte array")
|
arrayIdx != null -> TODO("in-place negate byte array")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #0
|
lda #0
|
||||||
@ -761,13 +830,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sbc $name+1
|
sbc $name+1
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
}
|
}
|
||||||
arrayIdx!=null -> TODO("in-place negate word array")
|
arrayIdx != null -> TODO("in-place negate word array")
|
||||||
memory!=null -> throw AssemblyError("no asm gen for word memory negate")
|
memory != null -> throw AssemblyError("no asm gen for word memory negate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when {
|
when {
|
||||||
identifier!=null -> {
|
identifier != null -> {
|
||||||
val name = asmgen.asmIdentifierName(identifier)
|
val name = asmgen.asmIdentifierName(identifier)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
@ -781,8 +850,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx ${C64Zeropage.SCRATCH_REG_X}
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
arrayIdx!=null -> TODO("in-place negate float array")
|
arrayIdx != null -> TODO("in-place negate float array")
|
||||||
memory!=null -> throw AssemblyError("no asm gen for float memory negate")
|
memory != null -> throw AssemblyError("no asm gen for float memory negate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("negate of invalid type")
|
else -> throw AssemblyError("negate of invalid type")
|
||||||
|
@ -7,79 +7,14 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
;ubyte @(addr)=0
|
uword addr = $c002
|
||||||
uword addr = $02
|
|
||||||
uword addr2 = $03
|
|
||||||
ubyte B = 22
|
|
||||||
; all optimized:
|
|
||||||
@(addr) = B
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr2-1) = @(addr2-1) +33
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
@(addr-2) = $f8
|
||||||
c64scr.print_ub(@(addr))
|
@(addr-2) = not @(addr-2)
|
||||||
|
c64scr.print_ubhex(@($c000), true)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
@(addr) = 33 + @(addr)
|
@(addr-2) = not @(addr-2)
|
||||||
c64scr.print_ub(@(addr))
|
c64scr.print_ubhex(@($c000), true)
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = (@(addr) + 33) + B
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = (33 + @(addr)) + B
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = (@(addr) + B) + 33
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = (B + @(addr)) + 33
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = B+ (@(addr) + 33)
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = B+(33 + @(addr))
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = 33+(@(addr) + B)
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
@(addr) = 11
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
@(addr) = 33+(B + @(addr))
|
|
||||||
c64scr.print_ub(@(addr))
|
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user