From b346cc85c5c7e2b19de619d3b2ead51929499b8e Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sat, 29 Feb 2020 12:16:54 +0100 Subject: [PATCH] more multiplication/division work --- CREDITS.md | 1 - STATUS.md | 2 +- c64/basic/math/bb12.div_FAC2_FAC1.s | 115 ++++---------------------- c64/basic/math/mul_FAC2_FAC1.s | 73 ++++++---------- c64/basic/math/muldiv_RESHO_helpers.s | 29 +++++++ 5 files changed, 75 insertions(+), 145 deletions(-) create mode 100644 c64/basic/math/muldiv_RESHO_helpers.s diff --git a/CREDITS.md b/CREDITS.md index c20920a0..a1ebe654 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -7,7 +7,6 @@ * Graham - for his PAL/NTSC detection routine * enthusi/Onslaught - for his example Turbo Tape 64 compatible loader * djmips - for fast 8x8 multiplication routine -* Verz - for integer division routine ## for documentation diff --git a/STATUS.md b/STATUS.md index ad5d7e75..05eb218a 100644 --- a/STATUS.md +++ b/STATUS.md @@ -199,7 +199,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B947` | `inv_FAC1_mantissa` | NOT DONE | | | `$B9EA` | `log_FAC1` | NOT DONE | | | `$BA28` | `mul_MEM_FAC1` | DONE | | -| `$BA2B` | `mul_FAC2_FAC1` | DONE | | +| `$BA2B` | `mul_FAC2_FAC1` | PARTIAL | needs retest after rework | | `$BA8C` | `mov_MEM_FAC2` | DONE | | | `$BA90` | `get_FAC2_via_INDEX` | NOT DONE | | | `$BAE2` | `mul10_FAC1` | DONE | | diff --git a/c64/basic/math/bb12.div_FAC2_FAC1.s b/c64/basic/math/bb12.div_FAC2_FAC1.s index 3d4878f0..328a9005 100644 --- a/c64/basic/math/bb12.div_FAC2_FAC1.s +++ b/c64/basic/math/bb12.div_FAC2_FAC1.s @@ -34,7 +34,7 @@ div_FAC2_FAC1: // Handle special case - dividing 0 by non-zero value lda FAC2_exponent - beq div_FAC2_FAC1_setexp_quit + beq_16 set_FAC1_zero // Multiply signs @@ -42,29 +42,32 @@ div_FAC2_FAC1: eor FAC2_sign sta FAC1_sign - // Subtract the exponents XXX what about bias? + // Subtract the exponents + + lda #($80 + $08) // correction for bias and shifted mantissa + sta RESHO+0 + lda #$00 + sta RESHO+1 lda FAC2_exponent + jsr muldiv_RESHO_01_add_A + + lda RESHO+0 sec sbc FAC1_exponent bcs !+ - // Result too low, set 0 and quit - - lda #$00 - -div_FAC2_FAC1_setexp_quit: - - sta FAC1_exponent - rts - + lda RESHO+1 + sbc #$00 + bcc_16 set_FAC1_zero // result too low, set 0 and quit !: - adc #$07 // add 8, as the carry is set here - bcs_16 set_FAC1_max // overflow - sta FAC1_exponent + lda RESHO+1 + bcc_16 set_FAC1_max // overflow // Divide the mantissas + jsr muldiv_RESHO_set_0 + // XXX @@ -74,87 +77,5 @@ div_FAC2_FAC1_setexp_quit: -// XXX adapt, move this to a separate file - -// Unsigned integer 32-bit division, based on code by Verz -// divident: FAC2_mantissa, divisor: FAC1_mantissa, result: FAC2_mantissa, remainder: RESHO -// temporary storage: INDEX+1, INDEX+2, INDEX+3 -// -// https://codebase64.org/doku.php?id=base:24bit_division_24-bit_result - -// XXX test this, optimize (for temporary storage use .Y, .Z and RESHO+4) - -div_mantissas: - - // Preset remainder to 0 - // XXX should be common with multiplication - - lda #$00 - sta RESHO+0 - sta RESHO+1 - sta RESHO+2 - sta RESHO+3 - - ldx #$32 // repeat for each bit - - // FALLTROUGH - -div_mantissas_loop: - - // Multiply divident by 2, msb -> Carry - - asl FAC2_mantissa+3 - rol FAC2_mantissa+2 - rol FAC2_mantissa+1 - rol FAC2_mantissa+0 - - // Multiply remainder by 2, lsb <- Carry - - rol RESHO+3 - rol RESHO+2 - rol RESHO+1 - rol RESHO+0 - - // Subtract divisor to see if it fits in - - lda RESHO+3 - sec - sbc FAC1_mantissa+2 - sta INDEX+3 - - lda RESHO+2 - sbc FAC1_mantissa+2 - sta INDEX+2 - - lda RESHO+1 - sbc FAC1_mantissa+1 - sta INDEX+1 - - lda RESHO+0 - sbc FAC1_mantissa+0 - bcc div_mantissas_skip // if Carry is not set then divisor did not fit in yet - - sta RESHO+0 // else save substraction result as new remainder, - lda INDEX+1 - sta RESHO+1 - lda INDEX+2 - sta RESHO+2 - lda INDEX+3 - sta RESHO+3 - - inc FAC2_mantissa+3 // and INCrement result cause divisor fit in 1 times - - // FALLTROUGH - -div_mantissas_skip: - - dex - bne div_mantissas_loop - - rts - - - - - +// XXX use 8-bit divide from here: https://codebase64.org/doku.php?id=base:8bit_divide_8bit_product diff --git a/c64/basic/math/mul_FAC2_FAC1.s b/c64/basic/math/mul_FAC2_FAC1.s index c42a213c..39fb256e 100644 --- a/c64/basic/math/mul_FAC2_FAC1.s +++ b/c64/basic/math/mul_FAC2_FAC1.s @@ -17,6 +17,11 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // +set_FAC1_zero: + + lda #$00 + sta FAC1_exponent + mul_FAC2_FAC1_done: rts @@ -39,59 +44,35 @@ mul_FAC2_FAC1: 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 + // Add the exponents (subtract the bias) XXX subroutines should be common with DIV - 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 - first clear the RESHO temporary area + jsr muldiv_RESHO_set_0 - lda #$00 + lda FAC1_exponent + jsr muldiv_RESHO_01_add_A + + lda FAC2_exponent + jsr muldiv_RESHO_01_add_A + + lda RESHO+0 + sbc #($80 - $08) // we need to correct double BIAS and shifted mantissa sta RESHO+0 + bcs !+ + lda RESHO+1 + sbc #$00 + bcs set_FAC1_zero sta RESHO+1 - sta RESHO+2 - sta RESHO+3 - sta RESHO+4 +!: + lda RESHO+1 + bne_16 set_FAC1_max // overflow + + lda RESHO+0 + sta FAC1_exponent // Multiply the mantissas + jsr muldiv_RESHO_set_0 + // XXX maybe we should preserve .X on stack? this will not cost us too much lda FACOV diff --git a/c64/basic/math/muldiv_RESHO_helpers.s b/c64/basic/math/muldiv_RESHO_helpers.s new file mode 100644 index 00000000..fef81a7b --- /dev/null +++ b/c64/basic/math/muldiv_RESHO_helpers.s @@ -0,0 +1,29 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - helper routines for RESHO manipulation +// + + +muldiv_RESHO_set_0: + + lda #$00 + sta RESHO+0 + sta RESHO+1 + sta RESHO+2 + sta RESHO+3 + sta RESHO+4 + + rts + +muldiv_RESHO_01_add_A: + + clc + adc RESHO+0 + sta RESHO+0 + bcc !+ + inc RESHO+1 +!: + rts