diff --git a/STATUS.md b/STATUS.md index 7c20cb47..69d469e1 100644 --- a/STATUS.md +++ b/STATUS.md @@ -199,7 +199,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B983` | `MULSHF` | NOT DONE | | | `$B9EA` | `log_FAC1` | NOT DONE | | | `$BA28` | `mul_MEM_FAC1` | PARTIAL | needs `mul_FAC2_FAC1` | -| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | | +| `$BA2B` | `mul_FAC2_FAC1` | NOT DONE | some work started | | `$BA59` | `MLTPLY` | NOT DONE | | | `$BA8C` | `mov_MEM_FAC2` | DONE | | | `$BAE2` | `mul10_FAC1` | NOT DONE | | diff --git a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s b/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s deleted file mode 100644 index f6659b85..00000000 --- a/c64/basic/,stubs_math/ba2b.mul_FAC2_FAC1.s +++ /dev/null @@ -1,24 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - multiplies FAC1 by FAC2 -// -// Input: -// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag -// -// Note: -// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -mul_FAC2_FAC1: - STUB_IMPLEMENTATION() diff --git a/c64/basic/math/add_FAC2_FAC1_sub.s b/c64/basic/math/add_FAC2_FAC1_sub.s index 24d20618..a045e1b8 100644 --- a/c64/basic/math/add_FAC2_FAC1_sub.s +++ b/c64/basic/math/add_FAC2_FAC1_sub.s @@ -12,7 +12,7 @@ add_FAC2_FAC1_sub: // First verify that |FAC1| > |FAC2|, branch to proper variant if it is not - // Note, that exponents are laready equalized + // We ignore FACOV here. Note, that exponents are already equalized lda FAC1_mantissa+0 cmp FAC2_mantissa+0 @@ -59,9 +59,7 @@ add_FAC2_FAC1_sub: sbc FAC2_mantissa+0 sta FAC1_mantissa+0 - bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent - - dec FAC1_exponent + // Exponent should never need adaptation here jmp normal_FAC1 @@ -94,14 +92,6 @@ add_FAC2_FAC1_sub_rev: sbc FAC1_mantissa+0 sta FAC1_mantissa+0 - bcs add_FAC2_FAC1_sub_normalize // end if no need to adapt the exponent - - lda FAC2_exponent - sta FAC1_exponent - dec FAC1_exponent - - // FALLTROUGH - -add_FAC2_FAC1_sub_normalize: + // Exponent should never need adaptation here jmp normal_FAC1 diff --git a/c64/basic/math/b86a.add_FAC2_FAC1.s b/c64/basic/math/b86a.add_FAC2_FAC1.s index 1e6bf6b9..9ae04a29 100644 --- a/c64/basic/math/b86a.add_FAC2_FAC1.s +++ b/c64/basic/math/b86a.add_FAC2_FAC1.s @@ -67,6 +67,10 @@ add_FAC2_FAC1: inc FAC1_exponent bne add_FAC2_FAC1_adapt_mantissa // end if no overflow + // FALLTROUGH + +set_FAC1_max: // entry used by other routines too + lda #$FF sta FAC1_exponent sta FAC1_mantissa+3 diff --git a/c64/basic/,stubs_math/ba2b.interop b/c64/basic/math/ba2b.interop similarity index 100% rename from c64/basic/,stubs_math/ba2b.interop rename to c64/basic/math/ba2b.interop diff --git a/c64/basic/math/ba2b.mul_FAC2_FAC1.s b/c64/basic/math/ba2b.mul_FAC2_FAC1.s new file mode 100644 index 00000000..1b918524 --- /dev/null +++ b/c64/basic/math/ba2b.mul_FAC2_FAC1.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 mul_FAC2_FAC1 diff --git a/c64/basic/math/mov_MEM_FAC1.s b/c64/basic/math/mov_MEM_FAC1.s index 6de5b9c8..f99cb9ee 100644 --- a/c64/basic/math/mov_MEM_FAC1.s +++ b/c64/basic/math/mov_MEM_FAC1.s @@ -22,7 +22,7 @@ // XXX test this mov_MEM_FAC1: -.break + // Original routines use $22/$23 location for a vector too, see here: // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics diff --git a/c64/basic/math/mul_FAC2_FAC1.s b/c64/basic/math/mul_FAC2_FAC1.s new file mode 100644 index 00000000..35b71b39 --- /dev/null +++ b/c64/basic/math/mul_FAC2_FAC1.s @@ -0,0 +1,90 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - multiplies FAC1 by FAC2 +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Note: +// - load FAC2 after FAC1, or mimic the Kernals sign comparison (XXX do we need it?) +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 113 XXX address does not match +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +mul_FAC2_FAC1: + + // First handle special case of multiplying by 0 + + lda FAC1_exponent + beq mul_FAC2_FAC1_done + + lda FAC2_exponent + bne !+ + sta FAC1_exponent + beq mul_FAC2_FAC1_done +!: + // Multiply signs + + lda FAC1_sign + eor FAC2_sign + sta FAC1_sign + + // Check if exponents can be added without overflow/underflow + + lda FAC1_exponent + and #$80 + eor FAC2_exponent + + bmi mul_FAC2_FAC1_add_exponents // exponent signs are opposite, we can add them safely + + // Both exponents are either negative (below $80), or both are non-negative ($80 or above), + // try to add them + + lda FAC1_exponent + clc + adc FAC2_exponent + bpl mul_FAC2_FAC1_sub_exp_bias // branch if we can add values + + // We cannot add them, result would over/underflow; set result as + // either 0 or maximum possible float + + lda FAC1_exponent + bmi_16 set_FAC1_max + + lda #$00 + sta FAC1_exponent + rts + +mul_FAC2_FAC1_add_exponents: + + // Add the exponents + + lda FAC1_exponent + clc + adc FAC2_exponent + + // FALLTROUGH + +mul_FAC2_FAC1_sub_exp_bias: + + sec + sbc #$80 // bias + sta FAC1_exponent + + // Multiply the mantissas + + // XXX + + STUB_IMPLEMENTATION() + +mul_FAC2_FAC1_done: + + rts