diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index 81045ea06..2b135abc2 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -146,22 +146,6 @@ push_float .proc rts .pend -func_rndf .proc - ; -- put a random floating point value on the stack - stx P8ZP_SCRATCH_REG - lda #1 - jsr FREADSA - jsr RND ; rng into fac1 - ldx #<_rndf_rnum5 - ldy #>_rndf_rnum5 - jsr MOVMF ; fac1 to mem X/Y - ldx P8ZP_SCRATCH_REG - lda #<_rndf_rnum5 - ldy #>_rndf_rnum5 - jmp push_float -_rndf_rnum5 .byte 0,0,0,0,0 - .pend - pop_float .proc ; ---- pops mflpt5 from stack to memory A/Y ; (frees 3 stack positions = 6 bytes of which 1 is padding) @@ -273,6 +257,14 @@ pop_2_floats_f2_in_fac1 .proc fmath_float1 .byte 0,0,0,0,0 ; storage for a mflpt5 value fmath_float2 .byte 0,0,0,0,0 ; storage for a mflpt5 value + +push_fac1 .proc + ; -- push the float in FAC1 onto the stack, usable as standalone + stx P8ZP_SCRATCH_REG + jmp push_fac1_as_result + .pend + + push_fac1_as_result .proc ; -- push the float in FAC1 onto the stack, and return from calculation ldx #c64.FL_LOG2 jsr MOVFM jsr FDIVT - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts .pend -func_sqrt .proc +func_sqrt_into_fac1 .proc jsr pop_float_fac1 stx P8ZP_SCRATCH_REG jsr SQR - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts .pend -func_rad .proc +func_rad_into_fac1 .proc ; -- convert degrees to radians (d * pi / 180) jsr pop_float_fac1 stx P8ZP_SCRATCH_REG lda #<_pi_div_180 ldy #>_pi_div_180 jsr FMULT - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts _pi_div_180 .byte 123, 14, 250, 53, 18 ; pi / 180 .pend -func_deg .proc +func_deg_into_fac1 .proc ; -- convert radians to degrees (d * (1/ pi * 180)) jsr pop_float_fac1 stx P8ZP_SCRATCH_REG lda #<_one_over_pi_div_180 ldy #>_one_over_pi_div_180 jsr FMULT - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts _one_over_pi_div_180 .byte 134, 101, 46, 224, 211 ; 1 / (pi * 180) .pend -func_round .proc +func_round_into_fac1 .proc jsr pop_float_fac1 stx P8ZP_SCRATCH_REG jsr FADDH jsr INT - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts .pend -func_floor .proc +func_floor_into_fac1 .proc jsr pop_float_fac1 stx P8ZP_SCRATCH_REG jsr INT - jmp push_fac1_as_result + ldx P8ZP_SCRATCH_REG + rts .pend -func_ceil .proc +func_ceil_into_fac1 .proc ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 jsr pop_float_fac1 stx P8ZP_SCRATCH_REG @@ -570,7 +584,8 @@ func_ceil .proc lda #FL_ONE_const jsr FADD -+ jmp push_fac1_as_result ++ ldx P8ZP_SCRATCH_REG + rts .pend func_any_f_into_A .proc @@ -629,7 +644,7 @@ func_all_f .proc rts .pend -func_max_f .proc +func_max_f_into_fac1 .proc lda #255 sta _minmax_cmp+1 lda #<_largest_neg_float @@ -657,22 +672,21 @@ _minmax_cmp cmp #255 ; modified cpy #255 bne - ldx floats_store_reg - stx P8ZP_SCRATCH_REG - jmp push_fac1_as_result + rts _largest_neg_float .byte 255,255,255,255,255 ; largest negative float -1.7014118345e+38 .pend -func_min_f .proc +func_min_f_into_fac1 .proc lda #1 - sta func_max_f._minmax_cmp+1 + sta func_max_f_into_fac1._minmax_cmp+1 lda #<_largest_pos_float ldy #>_largest_pos_float - jmp func_max_f._minmax_entry + jmp func_max_f_into_fac1._minmax_entry _largest_pos_float .byte 255,127,255,255,255 ; largest positive float rts .pend -func_sum_f .proc +func_sum_f_into_fac1 .proc lda #FL_ZERO_const jsr MOVFM @@ -694,8 +708,7 @@ func_sum_f .proc inc P8ZP_SCRATCH_W1+1 bne - + ldx floats_store_reg - stx P8ZP_SCRATCH_REG - jmp push_fac1_as_result + rts .pend sign_f .proc @@ -706,6 +719,25 @@ sign_f .proc rts .pend +set_array_float_from_fac1 .proc + ; -- set the float in FAC1 in the array (index in A, array in P8ZP_SCRATCH_W1) + sta P8ZP_SCRATCH_B1 + asl a + asl a + clc + adc P8ZP_SCRATCH_B1 + ldy P8ZP_SCRATCH_W1+1 + clc + adc P8ZP_SCRATCH_W1 + bcc + + iny ++ stx floats_store_reg + tax + jsr MOVMF + ldx floats_store_reg + rts + .pend + set_0_array_float .proc ; -- set a float in an array to zero (index in A, array in P8ZP_SCRATCH_W1) diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 9654708ca..c96fe45a3 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -58,7 +58,7 @@ fun compileProgram(filepath: Path, optimizeAst(programAst, errors) postprocessAst(programAst, errors, compilationOptions) - printAst(programAst) // TODO + // printAst(programAst) if(writeAssembly) programName = writeAssembly(programAst, errors, outputDir, optimize, compilationOptions) @@ -223,7 +223,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir: programAst.processAstBeforeAsmGeneration(errors) errors.handle() - printAst(programAst) // TODO + // printAst(programAst) CompilationTarget.instance.machine.initializeZeropage(compilerOptions) val assembly = CompilationTarget.instance.asmGenerator( diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index f6f17dafd..98cfb7417 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -48,7 +48,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val "sin", "cos", "tan", "atan", "ln", "log2", "sqrt", "rad", "deg", "round", "floor", "ceil", - "rdnf" -> funcVariousFloatFuncs(fcall, func, functionName, resultToStack) + "rndf" -> funcVariousFloatFuncs(fcall, func, functionName, resultToStack) "rnd", "rndw" -> funcRnd(functionName, resultToStack) "sqrt16" -> funcSqrt16(fcall, func, resultToStack) "rol" -> funcRol(fcall) @@ -389,11 +389,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, functionName: String, resultToStack: Boolean) { translateArguments(fcall.args, func) - if(resultToStack) { - asmgen.out(" jsr floats.func_$functionName") - } else { - TODO("float func result via registers $functionName") - } + asmgen.out(" jsr floats.func_${functionName}_into_fac1") + if(resultToStack) + asmgen.out(" jsr floats.push_fac1") } private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { @@ -414,7 +412,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.BYTE -> asmgen.out(" jsr math.sign_b_into_A") DataType.UWORD -> asmgen.out(" jsr math.sign_uw_into_A") DataType.WORD -> asmgen.out(" jsr math.sign_w_into_A") - DataType.FLOAT -> TODO("sign float using registers") + DataType.FLOAT -> asmgen.out(" jsr floats.pop_float_fac1 | jsr floats.SIGN") else -> throw AssemblyError("weird type $dt") } } @@ -449,7 +447,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${functionName}_b") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${functionName}_uw") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f_into_fac1 | jsr floats.push_fac1") else -> throw AssemblyError("weird type $dt") } } else { @@ -458,7 +456,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${functionName}_b_into_A") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${functionName}_uw_into_AY") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w_into_AY") - DataType.ARRAY_F -> TODO("min/max of floats result in float via registers") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f_into_fac1") else -> throw AssemblyError("weird type $dt") } } @@ -473,7 +471,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w") - DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_into_fac1 | jsr floats.push_fac1") else -> throw AssemblyError("weird type $dt") } } else { @@ -482,7 +480,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_into_AY") DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_into_AY") DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_into_AY") - DataType.ARRAY_F -> TODO("sum of floats result in float via registers") + DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_into_fac1") else -> throw AssemblyError("weird type $dt") } } @@ -877,7 +875,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt.typeOrElse(DataType.STRUCT)) { in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A") in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY") - DataType.FLOAT -> TODO("abs(float) via registers") + DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_into_fac1") else -> throw AssemblyError("weird type") } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index d202956f0..4c5843b00 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -174,7 +174,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY DataType.STR -> TODO("assign string => copy string or assign string address") - DataType.FLOAT -> TODO("assign float result from ${sub.name}") + DataType.FLOAT -> { + // float result from function sits in FAC1 + assignFAC1float(assign.target) + } else -> throw AssemblyError("weird result type") } } @@ -550,6 +553,38 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } + private fun assignFAC1float(target: AsmAssignTarget) { + when(target.kind) { + TargetStorageKind.VARIABLE -> { + asmgen.out(""" + stx P8ZP_SCRATCH_REG + ldx #<${target.asmVarname} + ldy #>${target.asmVarname} + jsr floats.MOVMF + ldx P8ZP_SCRATCH_REG + """) + } + TargetStorageKind.ARRAY -> { + asmgen.out(""" + lda #<${target.asmVarname} + ldy #>${target.asmVarname} + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1""") + if(target.array!!.indexer.indexNum!=null) { + val index = target.array.indexer.constIndex()!! + asmgen.out(" lda #$index") + } else { + val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!) + asmgen.out(" lda $asmvarname") + } + asmgen.out(" jsr floats.set_array_float_from_fac1") + } + TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte") + TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register") + TargetStorageKind.STACK -> asmgen.out(" jsr floats.push_fac1") + } + } + private fun assignVariableFloat(target: AsmAssignTarget, sourceName: String) { when(target.kind) { TargetStorageKind.VARIABLE -> { @@ -801,16 +836,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } private fun assignRegisterpairWord(target: AsmAssignTarget, regs: RegisterOrPair) { - require(target.datatype in NumericDatatypes) { - "zzz" - } - if(target.datatype==DataType.FLOAT) { - if (regs == RegisterOrPair.AY) { - asmgen.out(" brk ; TODO FLOAT RETURN VALUE") // TODO float value via registers - return - } - else throw AssemblyError("float reaturn value should be via AY return pointer") - } + require(target.datatype in NumericDatatypes) + if(target.datatype==DataType.FLOAT) + throw AssemblyError("float value should be from FAC1 not from registerpair memory pointer") + when(target.kind) { TargetStorageKind.VARIABLE -> { when(regs) { diff --git a/examples/cube3d-float.p8 b/examples/cube3d-float.p8 index a40cee432..87cd3fabe 100644 --- a/examples/cube3d-float.p8 +++ b/examples/cube3d-float.p8 @@ -4,6 +4,8 @@ ; Note: this program is compatible with C64 and CX16. +; TODO why has the prg become bigger since register args? + main { ; vertices diff --git a/examples/cube3d-gfx.p8 b/examples/cube3d-gfx.p8 index 570f60dce..8d650202d 100644 --- a/examples/cube3d-gfx.p8 +++ b/examples/cube3d-gfx.p8 @@ -3,6 +3,9 @@ ; Note: this program is compatible with C64 and CX16. +; TODO why has the prg become bigger since register args? + + main { ; vertices diff --git a/examples/cube3d.p8 b/examples/cube3d.p8 index dd8abda45..a062b5840 100644 --- a/examples/cube3d.p8 +++ b/examples/cube3d.p8 @@ -2,6 +2,8 @@ %import syslib %import textio +; TODO why has the prg become bigger since register args? + main { ; vertices diff --git a/examples/hello.p8 b/examples/hello.p8 index 25e099eb2..b34fde48b 100644 --- a/examples/hello.p8 +++ b/examples/hello.p8 @@ -5,6 +5,9 @@ ; Note: this program is compatible with C64 and CX16. +; TODO why has the prg become bigger since register args? + + main { sub start() { diff --git a/examples/plasma.p8 b/examples/plasma.p8 index 2e8547679..b2bf445b8 100644 --- a/examples/plasma.p8 +++ b/examples/plasma.p8 @@ -9,7 +9,7 @@ ; Converted to prog8 by Irmen de Jong. -; TODO why is the output of this larger with the register-eval stuff than before with the stack eval stuff? +; TODO why has the prg become bigger since register args? main { const uword SCREEN1 = $E000 diff --git a/examples/swirl-float.p8 b/examples/swirl-float.p8 index 9fd666dc3..dd3622a77 100644 --- a/examples/swirl-float.p8 +++ b/examples/swirl-float.p8 @@ -4,6 +4,8 @@ ; Note: this program is compatible with C64 and CX16. +; TODO why has the prg become bigger since register args? + main { struct Ball { diff --git a/examples/test.p8 b/examples/test.p8 index 32c0d0999..8561c90fb 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -9,25 +9,24 @@ main { sub start() { - str string1 = "abcdef" - str string2 = "%=&" - uword sa + float[] fls = [1.1, 2.2, 0.0, 4.4, 3.3] + float fl + ubyte ii - txt.print(string1) - txt.chrout('\n') - string1=string2 - txt.print(string1) + + fls[2] = sin(fls[0]) + for ii in 0 to len(fls)-1 { + floats.print_f(fls[ii]) + txt.chrout('\n') + } txt.chrout('\n') - void getstr() + fls[3] = cos(fls[0]) + for ii in 0 to len(fls)-1 { + floats.print_f(fls[ii]) + txt.chrout('\n') + } - sa = getstr() - txt.print_uwhex(sa, true) - txt.chrout('\n') - - string1 = getstr() - txt.print(string1) - txt.chrout('\n') ; fl = getfloat() ;