fix array in place assignments

fixes balls and snow examples amongst others
This commit is contained in:
Irmen de Jong 2023-03-10 04:07:50 +01:00
parent b7a6f3ec75
commit f350137a14
7 changed files with 90 additions and 47 deletions

View File

@ -130,7 +130,7 @@ class AsmGen6502Internal (
DataType.BYTE -> "cx16.r9sL"
DataType.UWORD -> "cx16.r9"
DataType.WORD -> "cx16.r9s"
DataType.FLOAT -> throw AssemblyError("a float tempvar should never be requested and it also doesn't exist")
DataType.FLOAT -> "floats.floats_temp_var"
else -> throw AssemblyError("invalid dt $dt")
}
}

View File

@ -44,8 +44,6 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
asmgen.asmVariableName(array.variable)
}
lateinit var origAssign: AsmAssignmentBase // TODO GET RID OF THIS
init {
if(register!=null && datatype !in NumericDatatypes)
throw AssemblyError("register must be integer or float type")

View File

@ -16,7 +16,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen)
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAssignment(source, target, program.memsizer, assignment.position)
target.origAssign = assign
translateNormalAssignment(assign)
}
@ -24,7 +23,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
val target = AsmAssignTarget.fromAstAssignment(augmentedAssign.target, augmentedAssign.definingISub(), asmgen)
val source = AsmAssignSource.fromAstSource(augmentedAssign.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAugmentedAssignment(source, augmentedAssign.operator, target, program.memsizer, augmentedAssign.position)
target.origAssign = assign
augmentableAsmGen.translate(assign)
}

View File

@ -204,41 +204,79 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
indexVar!=null -> {
when (target.datatype) {
in ByteDatatypes -> {
val tgt =
AsmAssignTarget.fromRegisters(
RegisterOrPair.A,
target.datatype == DataType.BYTE, target.position, null,
asmgen
)
target.toAstExpression()
TODO("ORIGASSIGN IS AsmAugmentedAssignment CLASS: $target $operator= $value")
val assign = AsmAssignment(target.origAssign.source, tgt, program.memsizer, target.position)
assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
asmgen.out(" lda ${target.array.variable.name},y | sta P8ZP_SCRATCH_B1")
asmgen.saveRegisterLocal(CpuRegister.Y, target.scope!!)
when {
valueLv != null -> inplaceModification_byte_litval_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_byte_variable_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, ident)
memread != null -> inplaceModification_byte_memread_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, memread)
value is PtTypeCast -> {
if (tryInplaceModifyWithRemovedRedundantCast(value, target, operator))
return
inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value)
}
else -> inplaceModification_byte_value_to_variable("P8ZP_SCRATCH_B1", target.datatype, operator, value)
}
asmgen.restoreRegisterLocal(CpuRegister.Y)
asmgen.out(" lda P8ZP_SCRATCH_B1 | sta ${target.array.variable.name},y")
}
in WordDatatypes -> {
val tgt =
AsmAssignTarget.fromRegisters(
RegisterOrPair.AY,
target.datatype == DataType.WORD, target.position, null,
asmgen
)
TODO("ORIGASSIGN IS AsmAugmentedAssignment CLASS: $target $operator= $value")
val assign = AsmAssignment(target.origAssign.source, tgt, program.memsizer, target.position)
assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
asmgen.out(" lda ${target.array.variable.name},y | sta P8ZP_SCRATCH_W1")
asmgen.out(" iny | lda ${target.array.variable.name},y | sta P8ZP_SCRATCH_W1+1")
asmgen.saveRegisterLocal(CpuRegister.Y, target.scope!!)
when {
valueLv != null -> inplaceModification_word_litval_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_word_variable_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, ident)
memread != null -> inplaceModification_word_memread_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, memread)
value is PtTypeCast -> {
if (tryInplaceModifyWithRemovedRedundantCast(value, target, operator))
return
inplaceModification_word_value_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value)
}
else -> inplaceModification_word_value_to_variable("P8ZP_SCRATCH_W1", target.datatype, operator, value)
}
asmgen.restoreRegisterLocal(CpuRegister.Y)
asmgen.out(" lda P8ZP_SCRATCH_W1+1 | sta ${target.array.variable.name},y")
asmgen.out(" lda P8ZP_SCRATCH_W1 | dey | sta ${target.array.variable.name},y")
}
DataType.FLOAT -> {
val tgt =
AsmAssignTarget.fromRegisters(
RegisterOrPair.FAC1,
true, target.position, null,
asmgen
)
TODO("ORIGASSIGN IS AsmAugmentedAssignment CLASS: $target $operator= $value")
val assign = AsmAssignment(target.origAssign.source, tgt, program.memsizer, target.position)
assignmentAsmGen.translateNormalAssignment(assign)
assignmentAsmGen.assignFAC1float(target)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.FLOAT, CpuRegister.A)
val tempvar = asmgen.getTempVarName(DataType.FLOAT)
asmgen.out("""
ldy #>${target.asmVarname}
clc
adc #<${target.asmVarname}
bcc +
iny
+ sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<$tempvar
ldy #>$tempvar
jsr floats.copy_float""") // copy from array into float temp var, clobbers A,Y
when {
valueLv != null -> inplaceModification_float_litval_to_variable(tempvar, operator, valueLv, target.scope!!)
ident != null -> inplaceModification_float_variable_to_variable(tempvar, operator, ident, target.scope!!)
value is PtTypeCast -> {
if (tryInplaceModifyWithRemovedRedundantCast(value, target, operator))
return
inplaceModification_float_value_to_variable(tempvar, operator, value, target.scope!!)
}
else -> inplaceModification_float_value_to_variable(tempvar, operator, value, target.scope!!)
}
asmgen.out("""
lda P8ZP_SCRATCH_W1
pha
lda P8ZP_SCRATCH_W1+1
pha
lda #<$tempvar
ldy #>$tempvar
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ply
pla
jsr floats.copy_float""") // copy from array into float temp var, clobbers A,Y
}
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
}

View File

@ -6,7 +6,7 @@ FL_LOG2_const .byte $80, $31, $72, $17, $f8 ; log(2)
floats_store_reg .byte 0 ; temp storage
floats_temp_var .byte 0,0,0,0,0 ; temporary storage for a float
ub2float .proc
; -- convert ubyte in SCRATCH_ZPB1 to float at address A/Y

View File

@ -3,8 +3,7 @@ TODO
For next minor release
^^^^^^^^^^^^^^^^^^^^^^
- fix flakes2_yy[idx]+=10 and -=10 not working. Error is in line 205+ in AugmentableAssignmentAsmGen. Snow example in cx16 (balls as well?)
- try to get rid of AsmAssignTarget.origAssign
- why did petaxian grow again since v8.10?
- fix Github issue with X register https://github.com/irmen/prog8/issues/94
- fix Github issue with array problems https://github.com/irmen/prog8/issues/99
- fix IR/VM: animals.p8 example is borked, it jumps straight to a suggestion and then somehow doesn't print the animal name correctly in the first question, and exits after 1 animal instead of looping

View File

@ -1,22 +1,32 @@
%import textio
%option no_sysinit
%zeropage basicsafe
%import floats
main {
sub start() {
ubyte[] array= [1,2,3]
uword[] array= [1111,2222,3333]
ubyte idx=1
txt.print_ub(array[idx])
txt.print_uw(array[idx])
txt.nl()
array[idx]+=10
txt.print_ub(array[idx])
array[idx]+=1234
txt.print_uw(array[idx])
txt.nl()
idx=2
txt.print_ub(idx)
ubyte[] array2= [11,22,33]
idx=1
txt.print_ub(array2[idx])
txt.nl()
idx+=10
txt.print_ub(idx)
array2[idx]+=34
txt.print_ub(array2[idx])
txt.nl()
float[] array3= [11.11,22.22,33.33]
idx=1
floats.print_f(array3[idx])
txt.nl()
array3[idx]+=55.66
floats.print_f(array3[idx])
txt.nl()
}
}