From ec3c7c05dcdb01dfa603dbe4e62c5b832b7af088 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sun, 3 May 2026 11:05:55 +0200 Subject: [PATCH] Add exp_FAC1 Had to deactivate it for MEGA65 because of conflicting code also placed at e000 --- STATUS.md | 2 +- src/basic/,stubs_math/bfed.exp_FAC1.s | 20 ------- src/basic/math_trans/bfed.exp_FAC1.s | 47 ++++++++++++++++ .../{,stubs_math => math_trans}/bfed.interop | 0 src/basic/math_trans/e000.exp_FAC1_contd.s | 53 +++++++++++++++++++ tools/similarity.c | 4 +- 6 files changed, 103 insertions(+), 23 deletions(-) delete mode 100644 src/basic/,stubs_math/bfed.exp_FAC1.s create mode 100644 src/basic/math_trans/bfed.exp_FAC1.s rename src/basic/{,stubs_math => math_trans}/bfed.interop (100%) create mode 100644 src/basic/math_trans/e000.exp_FAC1_contd.s diff --git a/STATUS.md b/STATUS.md index 50e67779..eb32c698 100644 --- a/STATUS.md +++ b/STATUS.md @@ -256,7 +256,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BF78` | `pwr_FAC2_MEM` | DONE | From the Microsoft BASIC, no label | | `$BF7B` | `pwr_FAC2_FAC1` | NOT DONE | | | `$BFB4` | `toggle_sign_FAC1` | DONE | From the Microsoft BASIC, original name: NEGOP | -| `$BFED` | `exp_FAC1` | NOT DONE | | +| `$BFED` | `exp_FAC1` | DONE | From the Microsoft BASIC, original name: EXP | | `$E043` | `poly1_FAC1` | DONE | From the Microsoft BASIC, original name: POLYX | | `$E059` | `poly2_FAC1` | DONE | From the Microsoft BASIC, original name: POLY | | `$E097` | `rnd_FAC1` | DONE | | diff --git a/src/basic/,stubs_math/bfed.exp_FAC1.s b/src/basic/,stubs_math/bfed.exp_FAC1.s deleted file mode 100644 index 4eb007f9..00000000 --- a/src/basic/,stubs_math/bfed.exp_FAC1.s +++ /dev/null @@ -1,20 +0,0 @@ -;; #LAYOUT# STD * #TAKE -;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -;; #LAYOUT# * BASIC_0 #TAKE -;; #LAYOUT# * * #IGNORE - -; -; Math package - exponential function, e raised to FAC1 power -; -; -; See also: -; - [CM64] Computes Mapping the Commodore 64 - page 117 -; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -; - -; XXX provide implementation - -exp_FAC1: - - +STUB_IMPLEMENTATION diff --git a/src/basic/math_trans/bfed.exp_FAC1.s b/src/basic/math_trans/bfed.exp_FAC1.s new file mode 100644 index 00000000..341d1dcf --- /dev/null +++ b/src/basic/math_trans/bfed.exp_FAC1.s @@ -0,0 +1,47 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; This file is under the MIT license, it contains code released by Microsoft Corporation. +; See LICENSE for more information. + +; Math package - exponential function, e raised to FAC1 power +; +; This is verified to be almost identical to the original Microsoft implementation where it was named EXP. +; The addition is the jmp between the two ROMs +; +; See also: +; - [CM64] Computes Mapping the Commodore 64 - page 117 +; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +; + +; FIRST SAVE THE ORIGINAL ARGUMENT AND MULTIPLY THE FAC BY +; LOG2(E). THE RESULT IS USED TO DETERMINE IF OVERFLOW +; WILL OCCUR SINCE EXP(X)=2^(X*LOG2(E)) WHERE +; LOG2(E)=LOG(E) BASE 2. THEN SAVE THE INTEGER PART OF +; THIS TO SCALE THE ANSWER AT THE END. SINCE +; 2^Y=2^INT(Y)*2^(Y-INT(Y)) AND 2^INT(Y) IS EASY TO COMPUTE. +; NOW COMPUTE 2^(X*LOG2(E)-INT(X*LOG2(E)) BY +; P(LN(2)*(INT(X*LOG2(E))+1)-X) WHERE P IS AN APPROXIMATION +; POLYNOMIAL. THE RESULT IS THEN SCALED BY THE POWER OF 2 +; PREVIOUSLY SAVED. + +!ifdef CONFIG_TRANSCENDENTAL_FUNCTIONS { +!ifdef CONFIG_MEMORY_MODEL_38K { + +exp_FAC1: + + lda #const_INV_LOG_2 + jsr mul_MEM_FAC1 + lda FACOV + adc #$50 + bcc @1 + jsr INCRND +@1 jmp STOLD ; The BASIC ROM ends here so we need to jump to the KERNAL ROM + + } else { + jmp do_NOT_IMPLEMENTED_error +} } diff --git a/src/basic/,stubs_math/bfed.interop b/src/basic/math_trans/bfed.interop similarity index 100% rename from src/basic/,stubs_math/bfed.interop rename to src/basic/math_trans/bfed.interop diff --git a/src/basic/math_trans/e000.exp_FAC1_contd.s b/src/basic/math_trans/e000.exp_FAC1_contd.s new file mode 100644 index 00000000..d9e99ea4 --- /dev/null +++ b/src/basic/math_trans/e000.exp_FAC1_contd.s @@ -0,0 +1,53 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; This file is under the MIT license, it contains code released by Microsoft Corporation. +; See LICENSE for more information. + +; Continuation of the exp function in the BASIC part of KERNAL ROM + +!ifdef CONFIG_TRANSCENDENTAL_FUNCTIONS { +!ifdef CONFIG_MEMORY_MODEL_38K { + +STOLD: + sta OLDOV + jsr mov_FAC1_FAC2 ; To save in FAC2 without ROUND + lda FAC1_exponent + cmp #$88 ; IF abs(FAC1) >= 128, too big + bcc @3 + +@2 + jsr MLDVEX ; overflow or overflow +@3 + jsr int_FAC1 + lda CHARAC ; Get low part + clc + adc #$81 + beq @2 ; overflow or overflow !! + sec + sbc #1 ; Subtract 1 + pha ; Save a while + ldx #5 ; Prep to swap FAC1 and FAC2 +@4 + lda FAC2_exponent,X + ldy FAC1_exponent,X + sta FAC1_exponent,X + sty FAC2_exponent,X + dex + bpl @4 + lda OLDOV + sta FACOV + jsr sub_FAC2_FAC1 + jsr toggle_sign_FAC1 ; Negate FAC1 + lda #poly_exp + jsr poly2_FAC1 + lda #$00 + sta ARISGN ; Multiply by positive 1.0 + pla ; Get scale factor + jsr MLDEXP ; Modify FAC1_exponent and check for overflow + rts + + } + } diff --git a/tools/similarity.c b/tools/similarity.c index 8b785db9..00f349bd 100644 --- a/tools/similarity.c +++ b/tools/similarity.c @@ -32,8 +32,8 @@ unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xB983, 0xBDC1, 0xBDDD, 0xBF51, 0xBF71, 0xBF7A, - 0xBFB4, 0xBFEC, - 0xE043, 0xE08C, + 0xBFB4, 0xBFFF, + 0xE000, 0xE08C, 0xE264, 0xE2C2, // Two byte gap here is an optimization 0xE2C5, 0xE37A, };