From 31ac4f8cdbae5309674be55874d9fba927f2af93 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 26 Feb 2025 20:43:58 +0100 Subject: [PATCH] Add int_FAC1 --- STATUS.md | 2 +- src/basic/,stubs_math/bccc.int_FAC1.s | 19 ----- src/basic/math/bccc.int_FAC1.jmp.s | 8 ++ src/basic/{,stubs_math => math}/bccc.interop | 0 src/basic/math/int_FAC1.s | 65 +++++++++++++++ strings/A590F004 | 3 + strings/A9BCA0B920 | 3 + strings/A9BCA0B92050B8A9 | 3 + strings/C8B17A85 | 3 + strings/FF856660 | 3 + testsuite/unit/math.vs | 83 ++++++++++++++++++++ 11 files changed, 172 insertions(+), 20 deletions(-) delete mode 100644 src/basic/,stubs_math/bccc.int_FAC1.s create mode 100644 src/basic/math/bccc.int_FAC1.jmp.s rename src/basic/{,stubs_math => math}/bccc.interop (100%) create mode 100644 src/basic/math/int_FAC1.s create mode 100644 strings/A590F004 create mode 100644 strings/A9BCA0B920 create mode 100644 strings/A9BCA0B92050B8A9 create mode 100644 strings/C8B17A85 create mode 100644 strings/FF856660 diff --git a/STATUS.md b/STATUS.md index baedadc5..8e27f439 100644 --- a/STATUS.md +++ b/STATUS.md @@ -238,7 +238,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BC58` | `abs_FAC1` | NOT DONE | | | `$BC5B` | `FCOMP` | DONE | | | `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | -| `$BCCC` | `int_FAC1` | NOT DONE | | +| `$BCCC` | `int_FAC1` | DONE | | | `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | | `$BD7E` | `FINLOG` | NOT DONE | | | `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | diff --git a/src/basic/,stubs_math/bccc.int_FAC1.s b/src/basic/,stubs_math/bccc.int_FAC1.s deleted file mode 100644 index 827fdaa5..00000000 --- a/src/basic/,stubs_math/bccc.int_FAC1.s +++ /dev/null @@ -1,19 +0,0 @@ -;; #LAYOUT# STD * #TAKE -;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -;; #LAYOUT# * BASIC_0 #TAKE -;; #LAYOUT# * * #IGNORE - -; -; Math package - rounds away the decimal to make an integer -; -; See also: -; - [CM64] Computes Mapping the Commodore 64 - page 116 -; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -; - -; XXX provide implementation - -int_FAC1: - - +STUB_IMPLEMENTATION diff --git a/src/basic/math/bccc.int_FAC1.jmp.s b/src/basic/math/bccc.int_FAC1.jmp.s new file mode 100644 index 00000000..c6e6e130 --- /dev/null +++ b/src/basic/math/bccc.int_FAC1.jmp.s @@ -0,0 +1,8 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; Just a compatibility jump - our routine is longer than original one + + jmp int_FAC1 diff --git a/src/basic/,stubs_math/bccc.interop b/src/basic/math/bccc.interop similarity index 100% rename from src/basic/,stubs_math/bccc.interop rename to src/basic/math/bccc.interop diff --git a/src/basic/math/int_FAC1.s b/src/basic/math/int_FAC1.s new file mode 100644 index 00000000..8e37b9ed --- /dev/null +++ b/src/basic/math/int_FAC1.s @@ -0,0 +1,65 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; +; Math package - rounds away the decimal to make an integer +; +; See also: +; - [CM64] Computes Mapping the Commodore 64 - page 116 +; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +; + +int_FAC1: + + lda FAC1_exponent + cmp #$81 + bcc int_FAC1_zero ; exponent is 0 or lower so integer part is 0 + cmp #$A0 + bcs int_FAC1_out ; exponent is 32 or larger so the entire mantissa is part of the integer + + tax + and #$07 ; low three bits of exponent is number of bits to keep + tay + + txa + lsr ; Bits 4-5 of exponent is how many full mantissa bytes to keep + lsr + lsr + and #$03 + tax + + lda #$FF ; Create bit mask for first mantissa byte to change +@1: lsr + dey + bne @1 + eor #$FF + + and FAC1_mantissa,X + sta FAC1_mantissa,X + lda #0 +@2: inx + cpx #$4 + bcs @3 + sta FAC1_mantissa,X + bcc @2 + +@3: lda FAC1_sign + bpl int_FAC1_out + lda #const_ONE + jsr sub_MEM_FAC1 ; FAC1 = 1 - FAC1 + lda #$FF + sta FAC1_sign ; FAC1 = FAC1 - 1 + rts + + + ; FIXME: Do we need to set FACOV to 0? + +int_FAC1_zero: + lda #0 + sta FAC1_exponent +int_FAC1_out: + rts diff --git a/strings/A590F004 b/strings/A590F004 new file mode 100644 index 00000000..62dc7ce7 --- /dev/null +++ b/strings/A590F004 @@ -0,0 +1,3 @@ +LDA $90 + BEQ $04 + +Check well known kernal i/o status variable in zero page diff --git a/strings/A9BCA0B920 b/strings/A9BCA0B920 new file mode 100644 index 00000000..b2336d4b --- /dev/null +++ b/strings/A9BCA0B920 @@ -0,0 +1,3 @@ +LDA #$BC + LDY #$B9 + JSR + +Load well known address of float constant 1.0 into Y:A and make call. diff --git a/strings/A9BCA0B92050B8A9 b/strings/A9BCA0B92050B8A9 new file mode 100644 index 00000000..213fbba7 --- /dev/null +++ b/strings/A9BCA0B92050B8A9 @@ -0,0 +1,3 @@ +LDA #$BC + LDY #$B9 + JSR $B850 + LDA + +Load well known address of float constant 1.0 and call subtract float. diff --git a/strings/C8B17A85 b/strings/C8B17A85 new file mode 100644 index 00000000..46bef245 --- /dev/null +++ b/strings/C8B17A85 @@ -0,0 +1,3 @@ +INY + BCS $7A + STA + +loop fragment diff --git a/strings/FF856660 b/strings/FF856660 new file mode 100644 index 00000000..914c4a88 --- /dev/null +++ b/strings/FF856660 @@ -0,0 +1,3 @@ +$FF + STA $66 + RTS + +Fragment of storing a negative value to FAC1 sign, which is a well knows address in the zero page. diff --git a/testsuite/unit/math.vs b/testsuite/unit/math.vs index d45a5c3c..6db037a0 100644 --- a/testsuite/unit/math.vs +++ b/testsuite/unit/math.vs @@ -233,4 +233,87 @@ ret print "CHECK A==0" r +print "TEST: int_FAC1 0.0" +fill $61 $61 00 +r PC=$BCCC +ret +fill $1001 $1001 00 +print "COMPARE" +compare $61 $61 $1001 +print "END" + +print "TEST: int_FAC1 1.0" +fill $61 $66 81 80 00 00 00 00 +r PC=$BCCC +ret +fill $1001 $1006 81 80 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 1.5" +fill $61 $66 81 C0 00 00 00 00 +r PC=$BCCC +ret +fill $1001 $1006 81 80 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 1.5" +fill $61 $66 81 C0 00 00 00 00 +r PC=$BCCC +ret +fill $1001 $1006 81 80 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 0.5" +fill $61 $66 80 80 00 00 00 00 +r PC=$BCCC +ret +fill $1001 $1001 00 +print "COMPARE" +compare $61 $61 $1001 +print "END" + +print "TEST: int_FAC1 4.00000006519258" +fill $61 $66 83 80 00 00 23 00 +r PC=$BCCC +ret +fill $1001 $1006 83 80 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 -4.00000006519258" +fill $61 $66 83 80 00 00 23 FF +r PC=$BCCC +ret +fill $1001 $1006 83 A0 00 00 00 FF +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 4398016684.0" +fill $61 $66 A1 83 12 34 56 00 +r PC=$BCCC +ret +fill $1001 $1006 A1 83 12 34 56 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: int_FAC1 134216.81774902344" +fill $61 $66 92 83 12 34 56 00 +r PC=$BCCC +ret +fill $1001 $1006 92 83 12 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + + + q