diff --git a/compiler/res/prog8lib/cx16textio.p8 b/compiler/res/prog8lib/cx16textio.p8 index 30127ee76..a8966debc 100644 --- a/compiler/res/prog8lib/cx16textio.p8 +++ b/compiler/res/prog8lib/cx16textio.p8 @@ -42,7 +42,7 @@ asmsub print (str text @ AY) clobbers(A,Y) { asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) { ; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total) %asm {{ - stx P8ZP_SCRATCH_REG_X + phx jsr conv.ubyte2decimal pha tya @@ -51,7 +51,7 @@ asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) { jsr c64.CHROUT txa jsr c64.CHROUT - ldx P8ZP_SCRATCH_REG_X + plx rts }} } @@ -59,7 +59,7 @@ asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) { asmsub print_ub (ubyte value @ A) clobbers(A,Y) { ; ---- print the ubyte in A in decimal form, without left padding 0s %asm {{ - stx P8ZP_SCRATCH_REG_X + phx jsr conv.ubyte2decimal _print_byte_digits pha @@ -76,7 +76,7 @@ _print_byte_digits jsr c64.CHROUT _ones txa jsr c64.CHROUT - ldx P8ZP_SCRATCH_REG_X + plx rts }} } @@ -84,7 +84,7 @@ _ones txa asmsub print_b (byte value @ A) clobbers(A,Y) { ; ---- print the byte in A in decimal form, without left padding 0s %asm {{ - stx P8ZP_SCRATCH_REG_X + phx pha cmp #0 bpl + @@ -93,7 +93,7 @@ asmsub print_b (byte value @ A) clobbers(A,Y) { + pla jsr conv.byte2decimal jsr print_ub._print_byte_digits - ldx P8ZP_SCRATCH_REG_X + plx rts }} } @@ -101,7 +101,7 @@ asmsub print_b (byte value @ A) clobbers(A,Y) { asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) { ; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well) %asm {{ - stx P8ZP_SCRATCH_REG_X + phx bcc + pha lda #'$' @@ -111,7 +111,7 @@ asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) { jsr c64.CHROUT tya jsr c64.CHROUT - ldx P8ZP_SCRATCH_REG_X + plx rts }} } @@ -119,7 +119,7 @@ asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) { asmsub print_ubbin (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) { ; ---- print the ubyte in A in binary form (if Carry is set, a radix prefix '%' is printed as well) %asm {{ - stx P8ZP_SCRATCH_REG_X + phx sta P8ZP_SCRATCH_B1 bcc + lda #'%' @@ -132,7 +132,7 @@ asmsub print_ubbin (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) { + jsr c64.CHROUT dey bne - - ldx P8ZP_SCRATCH_REG_X + plx rts }} } @@ -165,7 +165,7 @@ asmsub print_uwhex (uword value @ AY, ubyte prefix @ Pc) clobbers(A,Y) { asmsub print_uw0 (uword value @ AY) clobbers(A,Y) { ; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total) %asm {{ - stx P8ZP_SCRATCH_REG_X + phx jsr conv.uword2decimal ldy #0 - lda conv.uword2decimal.decTenThousands,y @@ -173,7 +173,7 @@ asmsub print_uw0 (uword value @ AY) clobbers(A,Y) { jsr c64.CHROUT iny bne - -+ ldx P8ZP_SCRATCH_REG_X ++ plx rts }} } @@ -181,9 +181,9 @@ asmsub print_uw0 (uword value @ AY) clobbers(A,Y) { asmsub print_uw (uword value @ AY) clobbers(A,Y) { ; ---- print the uword in A/Y in decimal form, without left padding 0s %asm {{ - stx P8ZP_SCRATCH_REG_X + phx jsr conv.uword2decimal - ldx P8ZP_SCRATCH_REG_X + plx ldy #0 - lda conv.uword2decimal.decTenThousands,y beq _allzero @@ -228,11 +228,11 @@ asmsub print_w (word value @ AY) clobbers(A,Y) { asmsub plot (ubyte col @ Y, ubyte row @ A) clobbers(A) { ; ---- safe wrapper around PLOT kernel routine, to save the X register. %asm {{ - stx P8ZP_SCRATCH_REG_X + phx tax clc jsr c64.PLOT - ldx P8ZP_SCRATCH_REG_X + plx rts }} } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 0d0d14a10..7044c7c07 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -551,7 +551,12 @@ internal class AsmGen(private val program: Program, internal fun saveRegister(register: CpuRegister) { when(register) { CpuRegister.A -> out(" pha") - CpuRegister.X -> out(" txa | pha") + CpuRegister.X -> { + if(CompilationTarget.machine.cpu == CpuType.CPU65c02) + out(" phx") + else + out(" stx P8ZP_SCRATCH_REG_X") + } CpuRegister.Y -> out(" tya | pha") } } @@ -559,7 +564,12 @@ internal class AsmGen(private val program: Program, internal fun restoreRegister(register: CpuRegister) { when(register) { CpuRegister.A -> out(" pla") - CpuRegister.X -> out(" pla | tax") + CpuRegister.X -> { + if(CompilationTarget.machine.cpu == CpuType.CPU65c02) + out(" plx") + else + out(" ldx P8ZP_SCRATCH_REG_X") + } CpuRegister.Y -> out(" pla | tay") } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 3a0a125de..704cf505a 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -18,7 +18,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}") val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam() if(saveX) - asmgen.out(" stx P8ZP_SCRATCH_REG_X") // we only save X for now (required! is the eval stack pointer), screw A and Y... + asmgen.saveRegister(CpuRegister.X) // we only save X for now (required! is the eval stack pointer), screw A and Y... val subName = asmgen.asmSymbolName(stmt.target) if(stmt.args.isNotEmpty()) { @@ -57,7 +57,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg asmgen.out(" jsr $subName") if(saveX) - asmgen.out(" ldx P8ZP_SCRATCH_REG_X") // restore X again + asmgen.restoreRegister(CpuRegister.X) } private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt index f198f30ad..81712dafc 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt @@ -97,7 +97,8 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg } else -> { asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A) - asmgen.out(" stx P8ZP_SCRATCH_REG_X | tax") + asmgen.saveRegister(CpuRegister.X) + asmgen.out(" tax") when(elementDt) { in ByteDatatypes -> { asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x") @@ -124,7 +125,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg } else -> throw AssemblyError("weird array elt dt") } - asmgen.out(" ldx P8ZP_SCRATCH_REG_X") + asmgen.restoreRegister(CpuRegister.X) } } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt index b6c5bf4ad..28a42b7a7 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -1059,11 +1059,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, // because the value is evaluated onto the eval stack (=slow). println("warning: slow stack evaluation used (2): $name $operator= ${value::class.simpleName} at ${value.position}") // TODO asmgen.translateExpression(value) + asmgen.saveRegister(CpuRegister.X) when (operator) { "**" -> { asmgen.out(""" jsr c64flt.pop_float_fac1 - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.CONUPK @@ -1073,7 +1073,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "+" -> { asmgen.out(""" jsr c64flt.pop_float_fac1 - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.FADD @@ -1082,7 +1081,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "-" -> { asmgen.out(""" jsr c64flt.pop_float_fac1 - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.FSUB @@ -1091,7 +1089,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "*" -> { asmgen.out(""" jsr c64flt.pop_float_fac1 - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.FMULT @@ -1100,7 +1097,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "/" -> { asmgen.out(""" jsr c64flt.pop_float_fac1 - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.FDIV @@ -1113,8 +1109,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, ldx #<$name ldy #>$name jsr c64flt.MOVMF - ldx P8ZP_SCRATCH_REG_X """) + asmgen.restoreRegister(CpuRegister.X) } private fun inplaceModification_float_variable_to_variable(name: String, operator: String, ident: IdentifierReference) { @@ -1123,10 +1119,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, throw AssemblyError("float variable expected") val otherName = asmgen.asmVariableName(ident) + asmgen.saveRegister(CpuRegister.X) when (operator) { "**" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.CONUPK @@ -1137,7 +1133,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } "+" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.MOVFM @@ -1148,7 +1143,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } "-" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$otherName ldy #>$otherName jsr c64flt.MOVFM @@ -1159,7 +1153,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } "*" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.MOVFM @@ -1170,7 +1163,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } "/" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$otherName ldy #>$otherName jsr c64flt.MOVFM @@ -1186,16 +1178,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, ldx #<$name ldy #>$name jsr c64flt.MOVMF - ldx P8ZP_SCRATCH_REG_X """) + asmgen.restoreRegister(CpuRegister.X) } private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) { val constValueName = asmgen.getFloatAsmConst(value) + asmgen.saveRegister(CpuRegister.X) when (operator) { "**" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.CONUPK @@ -1208,7 +1200,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, if (value == 0.0) return asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.MOVFM @@ -1221,7 +1212,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, if (value == 0.0) return asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$constValueName ldy #>$constValueName jsr c64flt.MOVFM @@ -1232,7 +1222,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } "*" -> { asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$name ldy #>$name jsr c64flt.MOVFM @@ -1245,7 +1234,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, if (value == 0.0) throw AssemblyError("division by zero") asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<$constValueName ldy #>$constValueName jsr c64flt.MOVFM @@ -1261,8 +1249,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, ldx #<$name ldy #>$name jsr c64flt.MOVMF - ldx P8ZP_SCRATCH_REG_X """) + asmgen.restoreRegister(CpuRegister.X) } private fun inplaceCast(target: AsmAssignTarget, cast: TypecastExpression, position: Position) { @@ -1499,8 +1487,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, DataType.FLOAT -> { when(target.kind) { TargetStorageKind.VARIABLE -> { + asmgen.saveRegister(CpuRegister.X) asmgen.out(""" - stx P8ZP_SCRATCH_REG_X lda #<${target.asmVarname} ldy #>${target.asmVarname} jsr c64flt.MOVFM @@ -1508,8 +1496,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, ldx #<${target.asmVarname} ldy #>${target.asmVarname} jsr c64flt.MOVMF - ldx P8ZP_SCRATCH_REG_X """) + asmgen.restoreRegister(CpuRegister.X) } TargetStorageKind.ARRAY -> TODO("in-place negate float array") TargetStorageKind.STACK -> TODO("stack float negate")