diff --git a/STATUS.md b/STATUS.md index 9b2d1f73..98646059 100644 --- a/STATUS.md +++ b/STATUS.md @@ -179,7 +179,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$B1AA` | `FACINX` | NOT DONE | convert FAC1 to 16-bit signed integer | | `$B391` | `GIVAYF` | NOT DONE | 16-bit signed integer to FAC1 | | `$B7B5` | `STRVAL` | NOT DONE | imports string to FAC1 | -| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `sub_FAC2_FAC1` | +| `$B850` | `sub_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B853` | `sub_FAC2_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B867` | `add_MEM_FAC1` | PARTIAL | needs `add_FAC2_FAC1` | | `$B86A` | `add_FAC2_FAC1` | NOT DONE | | @@ -193,11 +193,14 @@ Floating point mathematical routines - not official, but well known and broadly | `$BB0F` | `div_MEM_FAC1` | PARTIAL | needs `div_FAC2_FAC1` | | `$BB12` | `div_FAC2_FAC1` | NOT DONE | | | `$BBA2` | `mov_MEM_FAC1` | PARTIAL | not fully tested yet | -| `$BBD4` | `MOVFM2` | NOT DONE | copy FAC1 to memory location, rounds if asked | -| `$BBFC` | `MOVEF` | NOT DONE | copy FAC2 to FAC1 | -| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested | +| `$BBC7` | `mov_r_FAC1_TMP2` | PARTIAL | not fully tested yet | +| `$BBCA` | `mov_r_FAC1_TMP1` | PARTIAL | not fully tested yet | +| `$BBD0` | `mov_r_FAC1_VAR` | PARTIAL | not fully tested yet | +| `$BBD4` | `mov_r_FAC1_MEM` | PARTIAL | not fully tested yet | +| `$BBFC` | `mov_FAC2_FAC1` | PARTIAL | not fully tested yet | +| `$BC0C` | `mov_r_FAC1_FAC2` | PARTIAL | not fully tested yet | | `$BC0F` | `mov_FAC1_FAC2` | DONE | | -| `$BC1B` | `round_FAC1` | PARTIAL | not tested | +| `$BC1B` | `round_FAC1` | PARTIAL | not fully tested yet | | `$BC2B` | `sgn_FAC1_A` | NOT DONE | | | `$BC39` | `sgn_FAC1` | NOT DONE | | | `$BC58` | `abs_FAC1` | NOT DONE | | diff --git a/c64/basic/,stubs_math/bbfc.MOVEF.s b/c64/basic/,stubs_math/bbfc.MOVEF.s deleted file mode 100644 index b04de5b6..00000000 --- a/c64/basic/,stubs_math/bbfc.MOVEF.s +++ /dev/null @@ -1,17 +0,0 @@ -// #LAYOUT# STD * #TAKE -// #LAYOUT# * BASIC_0 #TAKE -// #LAYOUT# * * #IGNORE - -// -// Math package - copy FAC2 to FAC1 -// -// See also: -// - [CM64] Computes Mapping the Commodore 64 - page 115 -// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -// - -// XXX provide implementation - -MOVEF: - STUB_IMPLEMENTATION() diff --git a/c64/basic/,stubs_math/bbd4.interop b/c64/basic/math/bbc7.interop similarity index 100% rename from c64/basic/,stubs_math/bbd4.interop rename to c64/basic/math/bbc7.interop diff --git a/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s new file mode 100644 index 00000000..9fd4c393 --- /dev/null +++ b/c64/basic/math/bbc7.mov_r_FAC1_TMP2.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_r_FAC1_TMP2 diff --git a/c64/basic/,stubs_math/bbfc.interop b/c64/basic/math/bbca.interop similarity index 100% rename from c64/basic/,stubs_math/bbfc.interop rename to c64/basic/math/bbca.interop diff --git a/c64/basic/math/bbca.mov_r_FAC1_TMP1.s b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s new file mode 100644 index 00000000..1b3ed69c --- /dev/null +++ b/c64/basic/math/bbca.mov_r_FAC1_TMP1.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_r_FAC1_TMP1 diff --git a/c64/basic/math/bbd0.interop b/c64/basic/math/bbd0.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbd0.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/bbd0.mov_r_FAC1_VAR.s b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s new file mode 100644 index 00000000..2d34f663 --- /dev/null +++ b/c64/basic/math/bbd0.mov_r_FAC1_VAR.s @@ -0,0 +1,20 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - move FAC1 (rounds) to memory variable +// +// Input: +// - FORPNT ($49/$4A) - variable address +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// + +mov_r_FAC1_VAR: + + ldy #FORPNT+1 + ldx #FORPNT+0 + + // FALLTROUGH to mov_r_FAC1_MEM diff --git a/c64/basic/math/bbd4.interop b/c64/basic/math/bbd4.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbd4.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/,stubs_math/bbd4.MOVMF2.s b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s similarity index 68% rename from c64/basic/,stubs_math/bbd4.MOVMF2.s rename to c64/basic/math/bbd4.mov_r_FAC1_MEM.s index 850adaa5..26f898bd 100644 --- a/c64/basic/,stubs_math/bbd4.MOVMF2.s +++ b/c64/basic/math/bbd4.mov_r_FAC1_MEM.s @@ -3,12 +3,11 @@ // #LAYOUT# * * #IGNORE // -// Math package - copy FAC1 to memory location, rounds if asked +// Math package - copy FAC1 to memory location, do not round // // Input: // - .X - address low byte // - .Y - address high byte -// - $70 - if MSB is set performs rouding // // Output: // - .A - FAC1 exponent @@ -18,7 +17,9 @@ // - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics // -// XXX provide implementation +mov_r_FAC1_MEM: + + // Start by rounding FAC1 -MOVFM2: - STUB_IMPLEMENTATION() + jsr round_FAC1 + jmp mov_FAC1_MEM diff --git a/c64/basic/math/bbfc.interop b/c64/basic/math/bbfc.interop new file mode 100644 index 00000000..0d18777c --- /dev/null +++ b/c64/basic/math/bbfc.interop @@ -0,0 +1,3 @@ +This is an important floating point math routine, documented in many places. + +XXX - try to find real-life example diff --git a/c64/basic/math/bbfc.mov_FAC2_FAC1.s b/c64/basic/math/bbfc.mov_FAC2_FAC1.s new file mode 100644 index 00000000..509a911a --- /dev/null +++ b/c64/basic/math/bbfc.mov_FAC2_FAC1.s @@ -0,0 +1,7 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Just a compatibility jump - our routine is longer than original one + + jmp mov_FAC2_FAC1 diff --git a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s index 6dd59663..084d7e16 100644 --- a/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s +++ b/c64/basic/math/bc0c.mov_r_FAC1_FAC2.s @@ -14,7 +14,7 @@ // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic // -movr_FAC1_FAC2: +mov_r_FAC1_FAC2: // First round FAC1 jsr round_FAC1 diff --git a/c64/basic/math/mov_FAC1_MEM.s b/c64/basic/math/mov_FAC1_MEM.s new file mode 100644 index 00000000..9a8621fb --- /dev/null +++ b/c64/basic/math/mov_FAC1_MEM.s @@ -0,0 +1,77 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC1 to memory location, do not round +// +// Input: +// - .X - address low byte +// - .Y - address high byte +// +// Output: +// - .A - FAC1 exponent +// +// See also: +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +mov_FAC1_MEM: + + // Checked in the available documentation: + // - https://www.c64-wiki.com/wiki/Floating_point_arithmetic + // - https://www.lemon64.com/forum/viewtopic.php?t=67576&sid=d41e77cdddd28d6f9c9d52ce5b4e8dc3 + // that $22/$23 (INDEX+0 and INDEX+1) are at least sometimes used for pointer storage. + // Confirmed by experimenting with original ROM that this is the case here too. + + sty INDEX+1 + stx INDEX+0 + + ldy #$00 + + // Copy exponent + + lda FAC1_exponent + sta (INDEX), y + beq mov_FAC1_MEM_end // for 0 no need to copy anything more + + // Copy first byte of mantissa + + iny + lda FAC2_mantissa+3 + sta (INDEX), y + + // Copy the sign XXX try to optimize this part + + lda FAC1_sign + bne !+ + + lda FAC2_mantissa+3 + and #$7F + sta (INDEX), y +!: + // Copy remaining parts of mantissa + + iny + lda FAC2_mantissa+2 + sta (INDEX), y + + iny + lda FAC2_mantissa+1 + sta (INDEX), y + + iny + lda FAC2_mantissa+0 + sta (INDEX), y + + // Checked, that mov_FAC1_MEM works on real ROM too (at $BBD7), + // and clears FACOV in a similar way as mov_FAC1_FAC2 does (not surprising) + + ldy #$00 + sty FACOV + +mov_FAC1_MEM_end: + + lda FAC1_exponent + rts diff --git a/c64/basic/math/mov_FAC2_FAC1.s b/c64/basic/math/mov_FAC2_FAC1.s new file mode 100644 index 00000000..231c0b91 --- /dev/null +++ b/c64/basic/math/mov_FAC2_FAC1.s @@ -0,0 +1,49 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - copy FAC2 to FAC1 +// +// Output (found by experimentation): +// - .A - FAC1 exponent +// - .X - always 0 +// +// Preserves: +// - .Y +// +// See also: +// - [CM64] Computes Mapping the Commodore 64 - page 115 +// - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +// + +mov_FAC2_FAC1: + + // Copy the mantissa + + lda FAC2_mantissa+3 + sta FAC1_mantissa+3 + lda FAC2_mantissa+2 + sta FAC1_mantissa+2 + lda FAC2_mantissa+1 + sta FAC1_mantissa+1 + lda FAC2_mantissa+0 + sta FAC1_mantissa+0 + + // Copy the sign + + lda FAC2_sign + sta FAC1_sign + + // Copy the exponent + + lda FAC2_exponent + sta FAC1_exponent + + // Clear FACOV + + ldx #$00 + stx FACOV + + rts diff --git a/c64/basic/math/mov_r_FAC1_TMP1.s b/c64/basic/math/mov_r_FAC1_TMP1.s new file mode 100644 index 00000000..7edcf115 --- /dev/null +++ b/c64/basic/math/mov_r_FAC1_TMP1.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - store FAC1 (rounds) in TEMPF1 +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// + +mov_r_FAC1_TMP1: + + ldy #$00 + ldx #$5C + + jmp mov_r_FAC1_MEM diff --git a/c64/basic/math/mov_r_FAC1_TMP2.s b/c64/basic/math/mov_r_FAC1_TMP2.s new file mode 100644 index 00000000..3897d02a --- /dev/null +++ b/c64/basic/math/mov_r_FAC1_TMP2.s @@ -0,0 +1,18 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Math package - store FAC1 (rounds) in TEMPF2 +// +// See also: +// - https://www.c64-wiki.com/wiki/BASIC-ROM +// - https://sta.c64.org/cbm64basconv.html +// + +mov_r_FAC1_TMP2: + + ldy #$00 + ldx #$57 + + jmp mov_r_FAC1_MEM