From 77f3852cdcab518d4729d7976fb764deb69fab95 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 16 Aug 2023 14:47:20 +0200 Subject: [PATCH] added floats.parse_f() --- .idea/libraries/io_kotest_property_jvm.xml | 24 ---------------------- compiler/res/prog8lib/c64/floats.p8 | 12 ++++++++++- compiler/res/prog8lib/cx16/floats.p8 | 15 +++++++++++++- compiler/res/prog8lib/virtual/floats.p8 | 9 ++++++++ docs/source/libraries.rst | 11 ++++------ examples/test.p8 | 13 ++++-------- virtualmachine/src/prog8/vm/SysCalls.kt | 9 +++++++- 7 files changed, 50 insertions(+), 43 deletions(-) delete mode 100644 .idea/libraries/io_kotest_property_jvm.xml diff --git a/.idea/libraries/io_kotest_property_jvm.xml b/.idea/libraries/io_kotest_property_jvm.xml deleted file mode 100644 index 8649b4aac..000000000 --- a/.idea/libraries/io_kotest_property_jvm.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8 index 2a544754a..d90b7852b 100644 --- a/compiler/res/prog8lib/c64/floats.p8 +++ b/compiler/res/prog8lib/c64/floats.p8 @@ -46,7 +46,7 @@ romsub $b391 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) romsub $b3a2 = FREADUY(ubyte value @ Y) clobbers(A,X,Y) ; 8 bit unsigned Y -> float in fac1 romsub $bc3c = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 -romsub $b7b5 = FREADSTR(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $22/23 must point to string, A=string length +romsub $b7b5 = FREADSTR(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $22/23 must point to string, A=string length. Also see parse_f() romsub $aabc = FPRINTLN() clobbers(A,X,Y) ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well) romsub $bddd = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY ($0100) @@ -165,6 +165,16 @@ sub rndf() -> float { }} } +asmsub parse_f(str value @AY) -> float @FAC1 { + %asm {{ + sta $22 + sty $23 + jsr prog8_lib.strlen + tya + jmp FREADSTR + }} +} + %asminclude "library:c64/floats.asm" %asminclude "library:c64/floats_funcs.asm" diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index c5b8cb642..d63ab9512 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -28,7 +28,7 @@ romsub $fe00 = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 100-101 romsub $fe03 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) romsub $fe06 = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY -; romsub $fe09 = VAL_1() clobbers(A,X,Y) ; convert ASCII string to floating point [not yet implemented!!!] +; romsub $fe09 = VAL_1() clobbers(A,X,Y) ; convert ASCII string to floating point [not yet implemented!!!] see parse_f() instead ; GETADR: fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15) ; (tip: use GETADRAY to get A/Y output; lo/hi switched to normal little endian order) @@ -136,6 +136,19 @@ asmsub FREADUY (ubyte value @Y) { }} } +asmsub parse_f(str value @AY) -> float @FAC1 { + ; -- parse a string value of a number to float in FAC1 + ; warning: uses an internal BASIC routine that may be rom version dependent + ; ($ddf2 is inside the routine for VAL at $ddef) + %asm {{ + sta $a9 + sty $aa + jsr prog8_lib.strlen + tya + jmp $ddf2 + }} +} + &uword AYINT_facmo = $c6 ; $c6/$c7 contain result of AYINT diff --git a/compiler/res/prog8lib/virtual/floats.p8 b/compiler/res/prog8lib/virtual/floats.p8 index 976f733a2..4c2e209d9 100644 --- a/compiler/res/prog8lib/virtual/floats.p8 +++ b/compiler/res/prog8lib/virtual/floats.p8 @@ -16,6 +16,15 @@ sub print_f(float value) { }} } +sub parse_f(str value) -> float { + ; -- parse a string value of a number to float + %ir {{ + loadm.w r65535,floats.parse_f.value + syscall 45 (r65535.w): fr0.f + returnr.f fr0 + }} +} + sub pow(float value, float power) -> float { %ir {{ loadm.f fr0,floats.pow.value diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index a4874e826..2b0d2ec7a 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -312,13 +312,10 @@ point variables. This includes ``print_f``, the routine used to print floating ``rndseedf (seed)`` Sets a new seed for the float pseudo-RNG sequence. Use a negative non-zero number as seed value. -.. attention:: - A "parse" routine to convert a string into a floating point number is suspiciously absent. - This is because unfortunately there is no such routine available on each of the compiler targets. - Only the C64 target has the ``floats.FREADSTR()`` kernal routine that parses a string into a float into FAC1, - but the X16 has no equivalent in the kernal rom at this time. - The same is true for parsing an *integer* number however you can use the parse routines in the ``conv`` module as - a stepping stone to eventually load the number into FAC1 using one of the available kernal routines. +``parse_f (stringvalue)`` + Parses the string value as floating point number. + Warning: this routine may stop working on the Commander X16 when a new ROM version is released, + because it uses an internal BASIC routine. Then it will require a fix. graphics diff --git a/examples/test.p8 b/examples/test.p8 index 06a79e28e..f3d9c10ee 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,16 +1,11 @@ %import textio +%import string +%import floats %zeropage basicsafe main { sub start() { - ubyte value = 1 - uword wvalue = 1 - ubyte zero = 0 - txt.print_ub(value< { + val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort + val memstring = vm.memory.getString(stringAddr.toInt()) + returnValue(callspec.returns!!, memstring.toFloat(), vm) + } Syscall.COMPARE_STRINGS -> { val (firstV, secondV) = getArgValues(callspec.arguments, vm) val firstAddr = firstV as UShort