diff --git a/CREDITS.md b/CREDITS.md index a1ebe654..c20920a0 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -7,6 +7,7 @@ * 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 5a4fe399..1ef99cd7 100644 --- a/STATUS.md +++ b/STATUS.md @@ -205,7 +205,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BAE2` | `mul10_FAC1` | NOT DONE | | | `$BAFE` | `div10_FAC1_p` | NOT DONE | | | `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | -| `$BB12` | `div_FAC2_FAC1` | NOT DONE | | +| `$BB12` | `div_FAC2_FAC1` | NOT DONE | some work already started | | `$BBA2` | `mov_MEM_FAC1` | DONE | | | `$BBA6` | `get_FAC2_via_INDEX` | NOT DONE | | | `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | diff --git a/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s b/c64/basic/,stubs_math/bb12.div_FAC2_FAC1.s deleted file mode 100644 index 03f5b8db..00000000 --- a/c64/basic/,stubs_math/bb12.div_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 - divide FAC2 by FAC1, ignores sign -// -// Input: -// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag -// -// Output: -// - leaves the quotient FAC1 and the remainder in FAC2 -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 114 -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -div_FAC2_FAC1: - STUB_IMPLEMENTATION() diff --git a/c64/basic/math/bb12.div_FAC2_FAC1.s b/c64/basic/math/bb12.div_FAC2_FAC1.s new file mode 100644 index 00000000..51ad5f31 --- /dev/null +++ b/c64/basic/math/bb12.div_FAC2_FAC1.s @@ -0,0 +1,108 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - divide FAC2 (dividend) by FAC1 (divisor), ignores sign +// +// Input: +// - .A - must load FAC1 exponent ($61) beforehand to set the zero flag +// +// Output: +// - leaves the quotient FAC1 and the remainder in FAC2 +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 114 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +// XXX provide implementation + +div_FAC2_FAC1: + STUB_IMPLEMENTATION() + + + + + + +// XXX move this to a separate file + +// Unsigned integer 32-bit mantissa 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 diff --git a/c64/basic/,stubs_math/bb12.interop b/c64/basic/math/bb12.interop similarity index 100% rename from c64/basic/,stubs_math/bb12.interop rename to c64/basic/math/bb12.interop