diff --git a/compiler/compile.cmd b/compiler/compile.cmd index ac5050ff7..ab08a4165 100644 --- a/compiler/compile.cmd +++ b/compiler/compile.cmd @@ -1,6 +1,6 @@ set PROG8_LIBDIR=../prog8lib set PROG8CLASSPATH=out/production/compiler/ set KOTLINPATH=%USERPROFILE%/.IdeaIC2018.3/config/plugins/Kotlin -set LIBJARS=%KOTLINPATH%/lib/kotlin-stdlib.jar;%KOTLINPATH%/lib/kotlin-reflect.jar;antlr/lib/antlr-runtime-4.7.1.jar +set LIBJARS=%KOTLINPATH%/lib/kotlin-stdlib.jar;%KOTLINPATH%/lib/kotlin-reflect.jar;antlr/lib/antlr-runtime-4.7.2.jar java -Dprog8.libdir=%PROG8_LIBDIR% -cp %PROG8CLASSPATH%;%LIBJARS% prog8.CompilerMainKt %* diff --git a/compiler/compile.sh b/compiler/compile.sh index 1c6aa96ad..25c57615f 100755 --- a/compiler/compile.sh +++ b/compiler/compile.sh @@ -3,6 +3,6 @@ PROG8_LIBDIR=../prog8lib PROG8CLASSPATH=out/production/compiler KOTLINPATH=${HOME}/.IntelliJIdea2018.3/config/plugins/Kotlin -LIBJARS=${KOTLINPATH}/lib/kotlin-stdlib.jar:${KOTLINPATH}/lib/kotlin-reflect.jar:antlr/lib/antlr-runtime-4.7.1.jar +LIBJARS=${KOTLINPATH}/lib/kotlin-stdlib.jar:${KOTLINPATH}/lib/kotlin-reflect.jar:antlr/lib/antlr-runtime-4.7.2.jar java -Dprog8.libdir=${PROG8_LIBDIR} -cp ${PROG8CLASSPATH}:${LIBJARS} prog8.CompilerMainKt $* diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 11270da49..2adb2c8b2 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -6,23 +6,127 @@ ;c64scr.PLOT(screenx(x), screeny(y)) ; @todo fix argument calculation???!!! - ; @todo unify the type cast functions... "wrd(5)" -> "5 as word" - - ; @todo docs: "integer / int will not result in float but is integer floor division." verify this! - - sub toscreenx(float x, float z) -> word { - return 42.w as word - } - - asmsub blerp(ubyte x @ A, uword ding @ XY) -> clobbers() -> () { - word qq = A as word - } - sub start() { - word x = toscreenx(1.22, 3.22) - blerp(4, 555) + ubyte ub1 + ubyte ub2 + ubyte ub3 + byte b1 + byte b2 + byte b3 + uword uw1 + uword uw2 + uword uw3 + word w1 + word w2 + word w3 + float f1 + float f2 + float f3 + c64scr.print(" X=") + c64scr.print_ub(X) + c64.CHROUT('\n') + + ub1=20 + ub2=6 + ub3=ub1*ub2 + c64scr.print_ub(ub3) ; 120 + c64.CHROUT('\n') + uw1=900 + uw2=66 + uw3=uw1*uw2 + c64scr.print_uw(uw3) ; 59400 + c64.CHROUT('\n') + + b1=20 + b2=6 + b3=b1*b2 + c64scr.print_b(b3) ; 120 + c64.CHROUT('\n') + w1=500 + w2=44 + w3=w1*w2 + c64scr.print_w(w3) ; 22000 + c64.CHROUT('\n') + b1=20 + b2=-6 + b3=b1*b2 + c64scr.print_b(b3) ; -120 + c64.CHROUT('\n') + w1=500 + w2=-44 + w3=w1*w2 + c64scr.print_w(w3) ; -22000 + c64.CHROUT('\n') + b1=-20 + b2=-6 + b3=b1*b2 + c64scr.print_b(b3) ; 120 + c64.CHROUT('\n') + w1=-500 + w2=-44 + w3=w1*w2 + c64scr.print_w(w3) ; 22000 + c64.CHROUT('\n') + f1=-500.11 + f2=44.4 + f3=f1*f2 + c64flt.print_f(f3) + c64.CHROUT('\n') + + +; ub3 = 200/67 as ubyte +; ub3 = 200//67 +; c64scr.print_ub(ub3) +; c64.CHROUT('\n') +; ub3 = ub1/ub2 +; c64scr.print_ub(ub3) +; c64.CHROUT('\n') +; ub3 = ub1//ub2 +; c64scr.print_ub(ub3) +; c64.CHROUT('\n') +; +; uw3 = 2000/67 as uword +; c64scr.print_uw(uw3) +; c64.CHROUT('\n') +; uw3 = 2000//67 +; c64scr.print_uw(uw3) +; c64.CHROUT('\n') +; uw3 = uw1/uw2 +; c64scr.print_uw(uw3) +; c64.CHROUT('\n') +; uw3 = uw1//uw2 +; c64scr.print_uw(uw3) +; c64.CHROUT('\n') +; +; f3 = 999/44 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = 999//44 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = f1/f2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = f1//f2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = ub1/ub2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = ub1//ub2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = uw1/uw2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') +; f3 = uw1//uw2 +; c64flt.print_f(f3) +; c64.CHROUT('\n') + c64scr.print(" X=") + c64scr.print_ub(X) + c64.CHROUT('\n') ; const byte width=20 ; word w1 @@ -36,10 +140,10 @@ ; c64scr.print_byte(b1) ; c64.CHROUT('\n') ; ub1 = b2ub(fintb(x * flt(width)/4.2) + width//2) -; c64scr.print_ubyte(ub1) +; c64scr.print_ub(ub1) ; c64.CHROUT('\n') ; ub1 = b2ub(fintb(x/4.2 * flt(width)) + width//2) -; c64scr.print_ubyte(ub1) +; c64scr.print_ub(ub1) ; c64.CHROUT('\n') ; w1 = fintw(x * flt(width)/4.2) + width//2 ; c64scr.print_word(w1) diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 286261293..faca1a3e1 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -895,7 +895,7 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt") } DataType.FLOAT -> when(rightDt) { - in NumericDatatypes -> DataType.WORD + in NumericDatatypes -> DataType.FLOAT else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt") } else -> throw FatalAstException("arithmetic operation on incompatible datatypes: $leftDt and $rightDt") diff --git a/compiler/src/prog8/compiler/intermediate/Opcode.kt b/compiler/src/prog8/compiler/intermediate/Opcode.kt index c63ad70ff..1e34e768f 100644 --- a/compiler/src/prog8/compiler/intermediate/Opcode.kt +++ b/compiler/src/prog8/compiler/intermediate/Opcode.kt @@ -55,7 +55,7 @@ enum class Opcode { DIV_UW, DIV_W, DIV_F, - FLOORDIV, + FLOORDIV, // integer division but on floatint point argument(s) REMAINDER_UB, REMAINDER_B, REMAINDER_UW, diff --git a/compiler/src/prog8/compiler/intermediate/Value.kt b/compiler/src/prog8/compiler/intermediate/Value.kt index 190f7de04..026888a20 100644 --- a/compiler/src/prog8/compiler/intermediate/Value.kt +++ b/compiler/src/prog8/compiler/intermediate/Value.kt @@ -410,7 +410,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { DataType.UWORD -> Value(DataType.UWORD, numericValue()) DataType.WORD -> Value(DataType.WORD, numericValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } DataType.BYTE -> { @@ -420,7 +420,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535) DataType.WORD -> Value(DataType.WORD, integerValue()) DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } DataType.UWORD -> { @@ -434,7 +434,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { Value(DataType.WORD, -(65536-integerValue())) } DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } DataType.WORD -> { @@ -443,7 +443,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { DataType.UWORD -> Value(DataType.UWORD, integerValue() and 65535) DataType.WORD -> this DataType.FLOAT -> Value(DataType.FLOAT, numericValue()) - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } DataType.FLOAT -> { @@ -453,7 +453,7 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { if(integer in -128..127) Value(DataType.BYTE, integer) else - throw AstException("overflow when casting float to byte: $this") + throw AstException("overflow when casting float to byte: $this") // @todo ast-check for this } DataType.UBYTE -> Value(DataType.UBYTE, numericValue().toInt() and 255) DataType.UWORD -> Value(DataType.UWORD, numericValue().toInt() and 65535) @@ -462,13 +462,13 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { if(integer in -32768..32767) Value(DataType.WORD, integer) else - throw AstException("overflow when casting float to word: $this") + throw AstException("overflow when casting float to word: $this") // @todo ast-check for this } DataType.FLOAT -> this - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } - else -> throw ValueException("invalid type cast from $type to $targetType") + else -> throw ValueException("invalid type cast from $type to $targetType") // @todo ast-check for this } } diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 6f67412ef..7843333bc 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -690,11 +690,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " ${signExtendA("${ESTACK_HI+1},x")}" // sign extend the lsb @todo missing an lda??? Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x" - Opcode.DIV_UB -> " jsr prog8_lib.div_ub" - Opcode.DIV_B -> " jsr prog8_lib.div_b" - Opcode.DIV_F -> " jsr prog8_lib.div_f" - Opcode.DIV_W -> " jsr prog8_lib.div_w" - Opcode.DIV_UW -> " jsr prog8_lib.div_uw" Opcode.ADD_UB, Opcode.ADD_B -> { """ lda ${(ESTACK_LO + 2).toHex()},x @@ -713,15 +708,19 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${(ESTACK_LO + 1).toHex()},x """ } - Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_w" + Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_word" + Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_word" + Opcode.MUL_B, Opcode.MUL_UB -> " jsr prog8_lib.mul_byte" + Opcode.MUL_W, Opcode.MUL_UW -> " jsr prog8_lib.mul_word" Opcode.ADD_F -> " jsr prog8_lib.add_f" - Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_w" Opcode.SUB_F -> " jsr prog8_lib.sub_f" - Opcode.MUL_B -> " jsr prog8_lib.mul_b" - Opcode.MUL_UB -> " jsr prog8_lib.mul_ub" - Opcode.MUL_W -> " jsr prog8_lib.mul_w" - Opcode.MUL_UW -> " jsr prog8_lib.mul_uw" Opcode.MUL_F -> " jsr prog8_lib.mul_f" + Opcode.DIV_UB -> " jsr prog8_lib.div_ub" + Opcode.DIV_B -> " jsr prog8_lib.div_b" + Opcode.DIV_F -> " jsr prog8_lib.div_f" + Opcode.DIV_W -> " jsr prog8_lib.div_w" + Opcode.DIV_UW -> " jsr prog8_lib.div_uw" + Opcode.FLOORDIV -> " jsr prog8_lib.floordiv_f" Opcode.AND_BYTE -> { """ diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 1a1b638b9..82a10e8c7 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -432,11 +432,13 @@ You can also reference idendifiers defined elsewhere in your code. will be automatically converted into floats in this case. The compiler will issue a warning though when this happens, because floating point calculations are very slow and possibly unintended! - Calculations with integers will not result in floating point values; - if you divide two integer values (say: ``32500 / 99``) the result will be the integer floor + Calculations with integer variables will not result in floating point values. + if you divide two integer variables say 32500 and 99 the result will be the integer floor division (328) rather than the floating point result (328.2828282828283). If you need the full precision, - you'll have to make sure at least the first operand is a floating point. So write ``32500.0 / 99.0``, - or use the type cast ``value as float``. + you'll have to make sure at least the first operand is a floating point. You can do this by + using a floating point value or variable, or use a type cast. + When the compiler can calculate the result during compile-time, it will try to avoid loss + of precision though and gives an error if you may be losing a floating point result. diff --git a/prog8lib/c64utils.p8 b/prog8lib/c64utils.p8 index a0ec601c6..7fdbc2b80 100644 --- a/prog8lib/c64utils.p8 +++ b/prog8lib/c64utils.p8 @@ -280,7 +280,7 @@ asmsub GETADRAY () -> clobbers(X) -> (uword @ AY) { }} } -sub print_float (float value) { +sub print_f (float value) { ; ---- prints the floating point value (without a newline) using basic rom routines. ; clobbers no registers. ; @todo version that takes A/Y pointer to float instead @@ -290,8 +290,8 @@ sub print_float (float value) { pha txa pha - lda #print_float_value + lda #print_f_value jsr c64.MOVFM ; load float into fac1 jsr c64.FOUT ; fac1 to string in A/Y jsr c64.STROUT ; print string in A/Y @@ -304,7 +304,7 @@ sub print_float (float value) { }} } -sub print_float_ln (float value) { +sub print_fln (float value) { ; ---- prints the floating point value (with a newline at the end) using basic rom routines ; clobbers no registers. ; @todo version that takes A/Y pointer to float instead @@ -314,8 +314,8 @@ sub print_float_ln (float value) { pha txa pha - lda #print_float_ln_value + lda #print_fln_value jsr c64.MOVFM ; load float into fac1 jsr c64.FPRINTLN ; print fac1 with newline pla @@ -579,7 +579,7 @@ _scroll_screen ; scroll the screen memory -asmsub print_string (str text @ AY) -> clobbers(A,Y) -> () { +asmsub print (str text @ AY) -> clobbers(A,Y) -> () { ; ---- print null terminated string from A/Y ; note: the compiler contains an optimization that will replace ; a call to this subroutine with a string argument of just one char, @@ -598,7 +598,7 @@ asmsub print_string (str text @ AY) -> clobbers(A,Y) -> () { } -asmsub print_pstring (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) { +asmsub print_p (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) { ; ---- print pstring (length as first byte) from A/Y, returns str len in Y %asm {{ sta c64.SCRATCH_ZPB1 @@ -617,7 +617,7 @@ asmsub print_pstring (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) { } -asmsub print_ubyte0 (ubyte value @ A) -> clobbers(A,X,Y) -> () { +asmsub print_ub0 (ubyte value @ A) -> clobbers(A,X,Y) -> () { ; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total) %asm {{ jsr c64utils.ubyte2decimal @@ -632,7 +632,7 @@ asmsub print_ubyte0 (ubyte value @ A) -> clobbers(A,X,Y) -> () { } -asmsub print_ubyte (ubyte value @ A) -> clobbers(A,X,Y) -> () { +asmsub print_ub (ubyte value @ A) -> clobbers(A,X,Y) -> () { ; ---- print the ubyte in A in decimal form, without left padding 0s %asm {{ jsr c64utils.ubyte2decimal @@ -653,7 +653,7 @@ _print_tens txa }} } -asmsub print_byte (byte value @ A) -> clobbers(A,X,Y) -> () { +asmsub print_b (byte value @ A) -> clobbers(A,X,Y) -> () { ; ---- print the byte in A in decimal form, without left padding 0s %asm {{ pha @@ -663,12 +663,12 @@ asmsub print_byte (byte value @ A) -> clobbers(A,X,Y) -> () { jsr c64.CHROUT + pla jsr c64utils.byte2decimal - jmp print_ubyte._print_byte_digits + jmp print_ub._print_byte_digits }} } -asmsub print_ubyte_hex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () { +asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () { ; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well) %asm {{ bcc + @@ -684,21 +684,21 @@ asmsub print_ubyte_hex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) } -asmsub print_uword_hex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in hexadecimal form (4 digits) ; (if Carry is set, a radix prefix '$' is printed as well) %asm {{ pha tya - jsr print_ubyte_hex + jsr print_ubhex pla clc - jmp print_ubyte_hex + jmp print_ubhex }} } -asmsub print_uword0 (uword value @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_uw0 (uword value @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total) ; @todo shorter in loop form? %asm {{ @@ -717,7 +717,7 @@ asmsub print_uword0 (uword value @ AY) -> clobbers(A,X,Y) -> () { } -asmsub print_uword (uword value @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_uw (uword value @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in decimal form, without left padding 0s %asm {{ jsr c64utils.uword2decimal @@ -749,7 +749,7 @@ _pr_decimal }} } -asmsub print_word (word value @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_w (word value @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the (signed) word in A/Y in decimal form, without left padding 0s %asm {{ cpy #0 @@ -766,7 +766,7 @@ asmsub print_word (word value @ AY) -> clobbers(A,X,Y) -> () { adc #1 bcc + iny -+ jmp print_uword ++ jmp print_uw }} } diff --git a/prog8lib/mathlib.p8 b/prog8lib/mathlib.p8 index 81fab6f24..fd6b03c02 100644 --- a/prog8lib/mathlib.p8 +++ b/prog8lib/mathlib.p8 @@ -19,19 +19,19 @@ -asmsub multiply_bytes (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) -> (ubyte @ A) { +asmsub multiply_bytes (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers() -> (ubyte @ A) { ; ---- multiply 2 bytes, result as byte in A (signed or unsigned) %asm {{ - sta SCRATCH_ZPB1 - sty SCRATCH_ZPREG - ldx #8 -- asl a - asl SCRATCH_ZPB1 - bcc + - clc - adc SCRATCH_ZPREG -+ dex - bne - + sta SCRATCH_ZPB1 ; num1 + sty SCRATCH_ZPREG ; num2 + lda #0 + beq _enterloop +_doAdd clc + adc SCRATCH_ZPB1 +_loop asl SCRATCH_ZPB1 +_enterloop lsr SCRATCH_ZPREG + bcs _doAdd + bne _loop rts }} } @@ -58,41 +58,42 @@ asmsub multiply_bytes_16 (ubyte byte1 @ A, ubyte byte2 @ Y) -> clobbers(X) -> }} } - word[2] multiply_words_product = 0 asmsub multiply_words (uword number @ AY) -> clobbers(A,X) -> () { - ; ---- multiply two 16-bit words into a 32-bit result + ; ---- multiply two 16-bit words into a 32-bit result (signed and unsigned) ; input: A/Y = first 16-bit number, SCRATCH_ZPWORD1 in ZP = second 16-bit number - ; output: multiply_words_product 32-bits product, LSB order (low-to-high) + ; output: multiply_words.result 4-bytes/32-bits product, LSB order (low-to-high) %asm {{ sta SCRATCH_ZPWORD2 sty SCRATCH_ZPWORD2+1 mult16 lda #$00 - sta multiply_words_product+2 ; clear upper bits of product - sta multiply_words_product+3 + sta multiply_words_result+2 ; clear upper bits of product + sta multiply_words_result+3 ldx #16 ; for all 16 bits... - lsr SCRATCH_ZPWORD1+1 ; divide multiplier by 2 ror SCRATCH_ZPWORD1 bcc + - lda multiply_words_product+2 ; get upper half of product and add multiplicand + lda multiply_words_result+2 ; get upper half of product and add multiplicand clc adc SCRATCH_ZPWORD2 - sta multiply_words_product+2 - lda multiply_words_product+3 + sta multiply_words_result+2 + lda multiply_words_result+3 adc SCRATCH_ZPWORD2+1 + ror a ; rotate partial product - sta multiply_words_product+3 - ror multiply_words_product+2 - ror multiply_words_product+1 - ror multiply_words_product + sta multiply_words_result+3 + ror multiply_words_result+2 + ror multiply_words_result+1 + ror multiply_words_result dex bne - rts + +multiply_words_result .fill 4 + }} } - asmsub divmod_bytes (ubyte number @ X, ubyte divisor @ Y) -> clobbers() -> (ubyte @ X, ubyte @ A) { ; ---- divide X by Y, result quotient in X, remainder in A (unsigned) ; division by zero will result in quotient = 255 and remainder = original number diff --git a/prog8lib/prog8lib.p8 b/prog8lib/prog8lib.p8 index bbf57bd4f..3ec38efab 100644 --- a/prog8lib/prog8lib.p8 +++ b/prog8lib/prog8lib.p8 @@ -316,7 +316,18 @@ push_fac1_as_result .proc jmp push_float .pend - + +floordiv_f .proc + ; -- push f1//f2 on stack + jsr pop_2_floats_f2_in_fac1 + stx SCRATCH_ZPREGX + lda #fmath_float1 + jsr c64.FDIV + jsr c64.INT + jmp push_fac1_as_result + .pend + div_f .proc ; -- push f1/f2 on stack jsr pop_2_floats_f2_in_fac1 @@ -465,47 +476,80 @@ sub_w .proc rts .pend -mul_b .proc +mul_byte .proc + ; -- b*b->b (signed and unsigned) + inx + lda ESTACK_LO,x + ldy ESTACK_LO+1,x + jsr math.multiply_bytes + sta ESTACK_LO+1,x rts - .warn "mul_b not implemented" .pend -mul_ub .proc +mul_word .proc + inx + lda ESTACK_LO,x + sta SCRATCH_ZPWORD1 + lda ESTACK_HI,x + sta SCRATCH_ZPWORD1+1 + lda ESTACK_LO+1,x + ldy ESTACK_HI+1,x + stx SCRATCH_ZPREGX + jsr math.multiply_words + ldx SCRATCH_ZPREGX + lda math.multiply_words_result + sta ESTACK_LO+1,x + lda math.multiply_words_result+1 + sta ESTACK_HI+1,x rts - .warn "mul_ub not implemented" .pend -mul_w .proc - rts - .warn "mul_w not implemented" - .pend - -mul_uw .proc - rts - .warn "mul_uw not implemented" - .pend - div_b .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "div_b not implemented" .pend div_ub .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "div_ub not implemented" .pend div_w .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "div_w not implemented" .pend div_uw .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "div_uw not implemented" .pend remainder_b .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "remainder_b via div_b?" .pend @@ -524,18 +568,27 @@ remainder_ub .proc .pend remainder_w .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "remainder_w not implemented - via div_w" .pend remainder_uw .proc + inx + lda #42 + sta ESTACK_LO+1,x + lda #0 + sta ESTACK_HI+1,x rts .warn "remainder_uw not implemented - via div_uw" .pend equal_w .proc ; -- are the two words on the stack identical? - ; @todo optimize according to http://www.6502.org/tutorials/compare_beyond.html lda ESTACK_LO+1,x cmp ESTACK_LO+2,x bne equal_b._equal_b_false