From 5a3f65efa4b1aa505b7928f85749612de2ef29bc Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Tue, 1 Apr 2025 19:40:04 +0200 Subject: [PATCH] Add get_FAC1_via_INDEX Also change to only use bit 7 as sign in FAC1 and FAC2 (as the original BASIC does) to simplify implementations. --- STATUS.md | 2 +- .../,stubs_math/bba6.get_FAC1_via_INDEX.s | 17 ---- src/basic/math/FCOMP.s | 26 +++--- src/basic/math/bc2b.sgn_FAC1_A.s | 6 +- src/basic/math_mov/ba90.get_FAC2_via_INDEX.s | 12 +-- src/basic/math_mov/bba2.mov_MEM_FAC1.jmp.s | 8 -- src/basic/math_mov/bba2.mov_MEM_FAC1.s | 30 +++++++ src/basic/math_mov/bba6.get_FAC1_via_INDEX.s | 45 +++++++++++ .../{,stubs_math => math_mov}/bba6.interop | 0 src/basic/math_mov/mov_MEM_FAC1.s | 79 ------------------- ...B122856388B12285660980856288B1228561847060 | 3 + strings/20A2BB4C | 3 + strings/60202BBC85 | 5 ++ strings/6E0980856A88B1228569A56160 | 3 + ...A004B122856D88B122856C88B122856B88B122856E | 3 + strings/A9A8A0AE20A2BB4C | 3 + strings/B124456630 | 3 + testsuite/unit/math.vs | 16 +++- 18 files changed, 130 insertions(+), 134 deletions(-) delete mode 100644 src/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s delete mode 100644 src/basic/math_mov/bba2.mov_MEM_FAC1.jmp.s create mode 100644 src/basic/math_mov/bba2.mov_MEM_FAC1.s create mode 100644 src/basic/math_mov/bba6.get_FAC1_via_INDEX.s rename src/basic/{,stubs_math => math_mov}/bba6.interop (100%) delete mode 100644 src/basic/math_mov/mov_MEM_FAC1.s create mode 100644 strings/04B122856588B122856488B122856388B12285660980856288B1228561847060 create mode 100644 strings/20A2BB4C create mode 100644 strings/60202BBC85 create mode 100644 strings/6E0980856A88B1228569A56160 create mode 100644 strings/A004B122856D88B122856C88B122856B88B122856E create mode 100644 strings/A9A8A0AE20A2BB4C create mode 100644 strings/B124456630 diff --git a/STATUS.md b/STATUS.md index 422b7e4c..53bab291 100644 --- a/STATUS.md +++ b/STATUS.md @@ -222,7 +222,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BB0F` | `div_MEM_FAC1` | DONE | | | `$BB12` | `div_FAC2_FAC1` | DONE | | | `$BBA2` | `mov_MEM_FAC1` | DONE | | -| `$BBA6` | `get_FAC2_via_INDEX` | NOT DONE | | +| `$BBA6` | `get_FAC1_via_INDEX` | DONE | | | `$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 | diff --git a/src/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s b/src/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s deleted file mode 100644 index 81499d2f..00000000 --- a/src/basic/,stubs_math/bba6.get_FAC1_via_INDEX.s +++ /dev/null @@ -1,17 +0,0 @@ -;; #LAYOUT# STD * #TAKE -;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -;; #LAYOUT# * BASIC_0 #TAKE -;; #LAYOUT# * * #IGNORE - -; -; Math package - XXX -; -; See also: -; - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True -; - -; XXX implement, test - -get_FAC1_via_INDEX: - - +STUB_IMPLEMENTATION diff --git a/src/basic/math/FCOMP.s b/src/basic/math/FCOMP.s index f127dd4c..1a754efd 100644 --- a/src/basic/math/FCOMP.s +++ b/src/basic/math/FCOMP.s @@ -32,11 +32,9 @@ FCOMP: php ldy #$01 - lda #$7F ; Expand sign of RAM float into A as $FF or $00 - cmp (INDEX+2),Y - adc #$80 - cmp FAC1_sign - bne FCOMP_greater_than ; FAC < or > RAM, will be swapped to correct + lda (INDEX+2),Y + eor FAC1_sign ; Check if signs are different + bmi FCOMP_greater_than ; FAC < or > RAM, will be swapped to correct dey lda (INDEX+2),Y ; Exponent of RAM float into A @@ -76,17 +74,17 @@ FCOMP_equal: FCOMP_less_than: - lda #$FF - cmp FAC1_sign - bne @1 + lda FAC1_sign + bpl FCOMP_FF +FCOMP_01: lda #$01 -@1: plp + plp rts - + FCOMP_greater_than: - lda #$01 - cmp FAC1_sign - bcs @1 + lda FAC1_sign + bpl FCOMP_01 +FCOMP_FF: lda #$FF -@1: plp + plp rts diff --git a/src/basic/math/bc2b.sgn_FAC1_A.s b/src/basic/math/bc2b.sgn_FAC1_A.s index 0fb477ce..27b10ab6 100644 --- a/src/basic/math/bc2b.sgn_FAC1_A.s +++ b/src/basic/math/bc2b.sgn_FAC1_A.s @@ -20,7 +20,11 @@ sgn_FAC1_A: lda FAC1_exponent beq @1 lda FAC1_sign - bne @1 + bmi @2 lda #$01 @1: rts + +@2: + lda #$FF + rts diff --git a/src/basic/math_mov/ba90.get_FAC2_via_INDEX.s b/src/basic/math_mov/ba90.get_FAC2_via_INDEX.s index 508005f3..4b135a21 100644 --- a/src/basic/math_mov/ba90.get_FAC2_via_INDEX.s +++ b/src/basic/math_mov/ba90.get_FAC2_via_INDEX.s @@ -33,20 +33,10 @@ get_FAC2_via_INDEX: dey lda (INDEX), y + sta FAC2_sign ora #$80 ; clear the sign bit sta FAC2_mantissa+0 - ; Copy the sign - - lda (INDEX), y - bpl @1 ; assumption: non-negative numbers are more frequent - lda #$FF - +skip_2_bytes_trash_nvz -@1: - lda #$00 - - sta FAC2_sign - ; Copy the exponent dey diff --git a/src/basic/math_mov/bba2.mov_MEM_FAC1.jmp.s b/src/basic/math_mov/bba2.mov_MEM_FAC1.jmp.s deleted file mode 100644 index bad7d253..00000000 --- a/src/basic/math_mov/bba2.mov_MEM_FAC1.jmp.s +++ /dev/null @@ -1,8 +0,0 @@ -;; #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 mov_MEM_FAC1 diff --git a/src/basic/math_mov/bba2.mov_MEM_FAC1.s b/src/basic/math_mov/bba2.mov_MEM_FAC1.s new file mode 100644 index 00000000..4843ff8f --- /dev/null +++ b/src/basic/math_mov/bba2.mov_MEM_FAC1.s @@ -0,0 +1,30 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + + +; Math package - fetch FAC1 from RAM location +; +; Input: +; - .A - address low byte +; - .Y - address high byte +; +; Output: +; - .A - FAC1 exponent, affects status flags +; - .Y - always 0 +; +; Preserves: +; - .X - (experimentation with original ROM) +; +; See also: +; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics + + + +mov_MEM_FAC1: + sty INDEX+1 + sta INDEX+0 + + ; FALLTHROUGH to get_FAC1_via_INDEX diff --git a/src/basic/math_mov/bba6.get_FAC1_via_INDEX.s b/src/basic/math_mov/bba6.get_FAC1_via_INDEX.s new file mode 100644 index 00000000..cb29efa2 --- /dev/null +++ b/src/basic/math_mov/bba6.get_FAC1_via_INDEX.s @@ -0,0 +1,45 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; Math package - Mov MEM to FAC1 with address in INDEX zero page register +; +; See also: +; - https://sourceforge.net/p/acme-crossass/code-0/38/tree/trunk/ACME_Lib/cbm/c64/float.a?force=True +; + +get_FAC1_via_INDEX: + + ; Copy the mantissa + + ldy #$04 + lda (INDEX), y + sta FAC1_mantissa+3 + + dey + lda (INDEX), y + sta FAC1_mantissa+2 + + dey + lda (INDEX), y + sta FAC1_mantissa+1 + + dey + lda (INDEX), y + sta FAC1_sign + ora #$80 ; clear the sign bit + sta FAC1_mantissa+0 + + ; Copy the exponent + + dey + lda (INDEX), y + sta FAC1_exponent + + ; Set low order mantissa to 0 - this should give the + ; most precision while operating on integers + + sty FACOV + + rts diff --git a/src/basic/,stubs_math/bba6.interop b/src/basic/math_mov/bba6.interop similarity index 100% rename from src/basic/,stubs_math/bba6.interop rename to src/basic/math_mov/bba6.interop diff --git a/src/basic/math_mov/mov_MEM_FAC1.s b/src/basic/math_mov/mov_MEM_FAC1.s deleted file mode 100644 index 94ec6ad7..00000000 --- a/src/basic/math_mov/mov_MEM_FAC1.s +++ /dev/null @@ -1,79 +0,0 @@ -;; #LAYOUT# STD * #TAKE -;; #LAYOUT# * BASIC_0 #TAKE -;; #LAYOUT# * * #IGNORE - -; Math package - fetch FAC1 from RAM location -; -; Input: -; - .A - address low byte -; - .Y - address high byte -; -; Output: -; - .A - FAC1 exponent, affects status flags -; - .Y - always 0 -; -; Preserves: -; - .X - (experimentation with original ROM) -; -; See also: -; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics - -; XXX test this - -mov_MEM_FAC1: - - ; Original routines use $22/$23 location for a vector too, see here: - ; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics - - sty INDEX+1 - sta INDEX+0 - - ; Now copy the data from RAM to FAC2, for the format description see: - ; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic#Representation_in_the_C-64 - - ; Copy the mantissa - - ldy #$04 - lda (INDEX), y - sta FAC1_mantissa+3 - - dey - lda (INDEX), y - sta FAC1_mantissa+2 - - dey - lda (INDEX), y - sta FAC1_mantissa+1 - - dey - lda (INDEX), y - ora #$80 ; clear the sign bit - sta FAC1_mantissa+0 - - ; Copy the sign - - lda (INDEX), y - bpl @1 ; assumption: non-negative numbers are more frequent - lda #$FF - +skip_2_bytes_trash_nvz -@1: - lda #$00 - - sta FAC1_sign - - ; Copy the exponent - - dey - lda (INDEX), y - sta FAC1_exponent - - ; Set low order mantissa to 0 - this should give the - ; most precision while operating on integers - - sty FACOV - - ; Return the FAC1 exponent - - lda FAC1_exponent - rts diff --git a/strings/04B122856588B122856488B122856388B12285660980856288B1228561847060 b/strings/04B122856588B122856488B122856388B12285660980856288B1228561847060 new file mode 100644 index 00000000..04019ec9 --- /dev/null +++ b/strings/04B122856588B122856488B122856388B12285660980856288B1228561847060 @@ -0,0 +1,3 @@ +$04 + LDA ($22),Y + STA $65 + DEY + LDA ($22),Y + STA $64 + DEY + LDA ($22),Y + STA $63 + DEY + LDA ($22),Y + STA $66 + ORA #$80 + STA $62 + DEY + LDA ($22),Y + STA $61 + STY $70 + RTS + +Load FAC1 (well known zero page locations) from memory using well known vector in zero page (INDEX) diff --git a/strings/20A2BB4C b/strings/20A2BB4C new file mode 100644 index 00000000..77ad0c4f --- /dev/null +++ b/strings/20A2BB4C @@ -0,0 +1,3 @@ +JSR $BBA2 + JMP fragment + +Call to well known floating point function + fragment diff --git a/strings/60202BBC85 b/strings/60202BBC85 new file mode 100644 index 00000000..f29efa39 --- /dev/null +++ b/strings/60202BBC85 @@ -0,0 +1,5 @@ +60 20 2B BC 85 + +RTS + JSR $BC2B + STA fragment + +Fragments + call to well known floating point function diff --git a/strings/6E0980856A88B1228569A56160 b/strings/6E0980856A88B1228569A56160 new file mode 100644 index 00000000..d894ad6e --- /dev/null +++ b/strings/6E0980856A88B1228569A56160 @@ -0,0 +1,3 @@ +$6E + ORA #$80 + STA $6A + DEY + LDA ($22),Y + STA $69 + LDA $61 + RTS + +Fragment of copying using a well known index vector from a mem float into FAC2 diff --git a/strings/A004B122856D88B122856C88B122856B88B122856E b/strings/A004B122856D88B122856C88B122856B88B122856E new file mode 100644 index 00000000..c4f5496e --- /dev/null +++ b/strings/A004B122856D88B122856C88B122856B88B122856E @@ -0,0 +1,3 @@ +LDY #$04 + LDA ($22),Y + STA $6D + DEY + LDA ($22),Y + STA $6C + DEY + LDA ($22),Y + STA $6B + DEY + LDA ($22),Y + STA $6E + +Load parts of the mantissa of FAC2 and its sign (well known zero page locations) from memory using well known vector in zero page (INDEX) diff --git a/strings/A9A8A0AE20A2BB4C b/strings/A9A8A0AE20A2BB4C new file mode 100644 index 00000000..56912c73 --- /dev/null +++ b/strings/A9A8A0AE20A2BB4C @@ -0,0 +1,3 @@ +LDA #$A8 + LDY #$AE + JSR $BBA2 + JMP fragment + +Loading well known address of math constant pi into AY and call well known floating point function (mov_MEM_FAC1) diff --git a/strings/B124456630 b/strings/B124456630 new file mode 100644 index 00000000..af510266 --- /dev/null +++ b/strings/B124456630 @@ -0,0 +1,3 @@ +LDA ($24),Y + EOR $66 + BMI fragment + +Compare signs of FAC1 and float pointed to by index vector diff --git a/testsuite/unit/math.vs b/testsuite/unit/math.vs index 410aa3cb..d86a3330 100644 --- a/testsuite/unit/math.vs +++ b/testsuite/unit/math.vs @@ -139,12 +139,22 @@ r A=$E0 r Y=$B9 r PC=$BBA2 ret -fill $1001 $1006 80 80 00 00 00 FF +fill $1001 $1006 80 80 00 00 00 80 print "COMPARE" compare $61 $66 $1001 compare $70 $70 $1003 ; FACOV = 0 print "END" +print "TEST: get_FAC1_via_INDEX -0.5" +fill $61 $66 FF FF FF FF FF AA +fill $22 $23 E0 B9 +r PC=$BBA6 +ret +fill $1001 $1006 80 80 00 00 00 80 +print "COMPARE" +compare $61 $66 $1001 +print "END" + print "TEST: mov MEM FAC2 const 1.0" fill $69 $6E FF FF FF FF FF AA r A=$BC @@ -162,7 +172,7 @@ r A=$E0 r Y=$B9 r PC=$BA8C ret -fill $1001 $1006 80 80 00 00 00 FF +fill $1001 $1006 80 80 00 00 00 80 print "COMPARE" compare $69 $6E $1001 print "END" @@ -172,7 +182,7 @@ fill $69 $6E FF FF FF FF FF AA fill $22 $23 E0 B9 r PC=$BA90 ret -fill $1001 $1006 80 80 00 00 00 FF +fill $1001 $1006 80 80 00 00 00 80 print "COMPARE" compare $69 $6E $1001 print "END"