From 241cd603eb34daa8b7c0ed48b3aa535d79d13d29 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Thu, 13 Mar 2025 21:12:41 +0100 Subject: [PATCH] Add FIN --- STATUS.md | 2 +- src/basic/,stubs_math/bcf3.FIN.s | 25 --- src/basic/math/FIN.s | 155 +++++++++++++++++++ src/basic/math/bcf3.FIN.jmp.s | 12 ++ src/basic/{,stubs_math => math}/bcf3.interop | 0 strings/0A0A1865 | 3 + strings/2073004C | 3 + strings/20E2BA20 | 3 + strings/20FEBAE6 | 3 + strings/5D20E2BA | 3 + strings/60207300 | 3 + strings/6020730090 | 3 + strings/6AB8A55E | 3 + strings/856660A5 | 3 + strings/8570A565 | 3 + strings/C92DD004 | 3 + strings/C9309004C93C90 | 3 + strings/D0F9A567 | 3 + testsuite/unit/math.vs | 118 ++++++++++++++ 19 files changed, 325 insertions(+), 26 deletions(-) delete mode 100644 src/basic/,stubs_math/bcf3.FIN.s create mode 100644 src/basic/math/FIN.s create mode 100644 src/basic/math/bcf3.FIN.jmp.s rename src/basic/{,stubs_math => math}/bcf3.interop (100%) create mode 100644 strings/0A0A1865 create mode 100644 strings/2073004C create mode 100644 strings/20E2BA20 create mode 100644 strings/20FEBAE6 create mode 100644 strings/5D20E2BA create mode 100644 strings/60207300 create mode 100644 strings/6020730090 create mode 100644 strings/6AB8A55E create mode 100644 strings/856660A5 create mode 100644 strings/8570A565 create mode 100644 strings/C92DD004 create mode 100644 strings/C9309004C93C90 create mode 100644 strings/D0F9A567 diff --git a/STATUS.md b/STATUS.md index ccb89dec..5e17aebe 100644 --- a/STATUS.md +++ b/STATUS.md @@ -239,7 +239,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BC5B` | `FCOMP` | DONE | | | `$BC9B` | `QINT` | NOT DONE | convert FAC1 to 32 bit signed integer | | `$BCCC` | `int_FAC1` | DONE | | -| `$BCF3` | `FIN` | NOT DONE | imports string to FAC1, ignores spaces | +| `$BCF3` | `FIN` | PARTIAL | Only for 38k memory model + not fully tested yet | | `$BD7E` | `FINLOG` | NOT DONE | | | `$BDDD` | `FOUT` | NOT DONE | outputs FAC1 to string at $0100 | | `$BF71` | `sqr_FAC1` | PARTIAL | needs `sqr_FAC2` | diff --git a/src/basic/,stubs_math/bcf3.FIN.s b/src/basic/,stubs_math/bcf3.FIN.s deleted file mode 100644 index d5375a5e..00000000 --- a/src/basic/,stubs_math/bcf3.FIN.s +++ /dev/null @@ -1,25 +0,0 @@ -;; #LAYOUT# STD * #TAKE -;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 -;; #LAYOUT# * BASIC_0 #TAKE -;; #LAYOUT# * * #IGNORE - -; -; Math package - imports string to FAC1, ignores spaces -; -; -; Input: -; - .A needs to be loaded with first char of the string -; - Carry flag must be clear -; - string address in $7A/$7B -; -; See also: -; - [CM64] Computes Mapping the Commodore 64 - page 116 -; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic -; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics -; - -; XXX provide implementation - -FIN: - - +STUB_IMPLEMENTATION diff --git a/src/basic/math/FIN.s b/src/basic/math/FIN.s new file mode 100644 index 00000000..50051527 --- /dev/null +++ b/src/basic/math/FIN.s @@ -0,0 +1,155 @@ +;; #LAYOUT# STD * #TAKE +;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000 +;; #LAYOUT# * BASIC_0 #TAKE +;; #LAYOUT# * * #IGNORE + +; +; Math package - imports string to FAC1, ignores spaces +; +; +; Input: +; - .A needs to be loaded with first char of the string +; - Carry flag must be clear +; - string address in $7A/$7B +; +; See also: +; - [CM64] Computes Mapping the Commodore 64 - page 116 +; - https://www.c64-wiki.com/wiki/Floating_point_arithmetic +; - https://codebase64.org/doku.php?id=base:kernal_floating_point_mathematics +; + +!ifdef CONFIG_MEMORY_MODEL_38K { +; NOTE: Currently CHRGET is only available for the 38K model and the equivalent function +; does not test for digits to set carry + +FIN_NUMDEC = TEMPF2 +FIN_DIGIT = TEMPF2 + 1 +FIN_DECFOUND = TEMPF2 + 2 +FIN_EXPSIGN = TEMPF2 + 3 +FIN_EXP = TEMPF2 + 4 + + +FIN: + ldx #$00 + stx SGNFLG ; Sign is positive + stx FIN_DECFOUND ; Decimal point not found + stx FIN_EXP ; Exponent + stx FAC1_exponent ; FAC1 <- 0 + bcc FIN_loop ; Starting with digit + cmp #$2D ; Is minus? + bne @1 + dec SGNFLG + bne FIN_next ; Will always branch + +@1: cmp #$2B ; Is plus? + beq FIN_next + +FIN_loop: + bcs FIN_nonnumeric + sec + sbc #48 ; Convert to number + sta FIN_DIGIT + jsr mul10_FAC1 + jsr mov_FAC1_FAC2 + lda FIN_DIGIT + jsr convert_A_to_FAC1 + jsr add_FAC2_FAC1 + + lda FIN_DECFOUND ; Have we passed the decimal sign? + bpl FIN_next + inc FIN_NUMDEC + +FIN_next: + jsr CHRGET + +bra FIN_loop + +FIN_nonnumeric: + cmp #$2E ; decimal point + beq FIN_decimal + cmp #$45 ; E + beq FIN_exponent +FIN_finalize: + lda FIN_EXP + sec + sbc FIN_NUMDEC + sta FIN_EXP + bmi FIN_div_loop + +FIN_mul_loop: + dec FIN_EXP + bmi FIN_out + jsr mul10_FAC1 + +bra FIN_mul_loop + +FIN_div_loop: + jsr div10_FAC1_p + inc FIN_EXP + bne FIN_div_loop + +FIN_out: + lda SGNFLG + sta FAC1_sign + rts + +FIN_decimal: + lda FIN_DECFOUND + bmi FIN_finalize + dec FIN_DECFOUND ; Indicate found decimal point + sta FIN_NUMDEC ; Number of decimal places = 0 + +bra FIN_next + +FIN_exponent: + ldx #0 + stx FIN_EXPSIGN + jsr CHRGET + bcc FIN_exp_loop + cmp #$2D ; Is minus? + bne @1 + dec FIN_EXPSIGN + bne FIN_exp_next ; Always branches +@1: cmp #$2B ; Is plus? + beq FIN_exp_next + bne FIN_done_exp + +FIN_exp_loop: + tax + lda FIN_EXP + cmp #10 + bcs FIN_exp_limit + asl ; Multiply by 10 + sta FIN_EXP + asl + asl + clc + adc FIN_EXP + sta FIN_EXP + txa + sec + sbc #48 ; Convert to number + clc + adc FIN_EXP + sta FIN_EXP + +FIN_exp_next: + jsr CHRGET + bcc FIN_exp_loop + +FIN_done_exp: + lda FIN_EXP + bpl FIN_finalize + eor #$FF + tax + inx + stx FIN_EXP + +bra FIN_finalize + +FIN_exp_limit: + ldx FIN_EXPSIGN + bmi FIN_zero + jmp do_OVERFLOW_error + +FIN_zero: + ldx #0 + stx FAC1_exponent + rts + } diff --git a/src/basic/math/bcf3.FIN.jmp.s b/src/basic/math/bcf3.FIN.jmp.s new file mode 100644 index 00000000..1a4b9147 --- /dev/null +++ b/src/basic/math/bcf3.FIN.jmp.s @@ -0,0 +1,12 @@ +;; #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 + +!ifdef CONFIG_MEMORY_MODEL_38K { + jmp FIN +} else { + +STUB_IMPLEMENTATION +} diff --git a/src/basic/,stubs_math/bcf3.interop b/src/basic/math/bcf3.interop similarity index 100% rename from src/basic/,stubs_math/bcf3.interop rename to src/basic/math/bcf3.interop diff --git a/strings/0A0A1865 b/strings/0A0A1865 new file mode 100644 index 00000000..b337c666 --- /dev/null +++ b/strings/0A0A1865 @@ -0,0 +1,3 @@ +ASL + ASL + CLC + ADC fragment + +Multiply by 4 and add. Common fragment for multiplication by 10 or other constants. diff --git a/strings/2073004C b/strings/2073004C new file mode 100644 index 00000000..e3ae2118 --- /dev/null +++ b/strings/2073004C @@ -0,0 +1,3 @@ +JSR $0073 + JMP fragment + +Call well known address in zero page + fragment diff --git a/strings/20E2BA20 b/strings/20E2BA20 new file mode 100644 index 00000000..a20f251e --- /dev/null +++ b/strings/20E2BA20 @@ -0,0 +1,3 @@ +JSR $BAE2 + JSR fragment + +Call well known floating point function + fragment diff --git a/strings/20FEBAE6 b/strings/20FEBAE6 new file mode 100644 index 00000000..7c03055a --- /dev/null +++ b/strings/20FEBAE6 @@ -0,0 +1,3 @@ +JSR $BAFE + INC fragment + +Call to well known floating point function + fragment diff --git a/strings/5D20E2BA b/strings/5D20E2BA new file mode 100644 index 00000000..6279163e --- /dev/null +++ b/strings/5D20E2BA @@ -0,0 +1,3 @@ +$5D + JSR $BAE2 + +Fragment + call to well known floating point function diff --git a/strings/60207300 b/strings/60207300 new file mode 100644 index 00000000..c9ddfed2 --- /dev/null +++ b/strings/60207300 @@ -0,0 +1,3 @@ +RTS + JSR $0073 + +Fragment + call well known subrouting in zero page diff --git a/strings/6020730090 b/strings/6020730090 new file mode 100644 index 00000000..adffe13f --- /dev/null +++ b/strings/6020730090 @@ -0,0 +1,3 @@ +RTS + JSR $0073 + BCC fragment + +Fragments + Call to well known zero page address diff --git a/strings/6AB8A55E b/strings/6AB8A55E new file mode 100644 index 00000000..084dcebd --- /dev/null +++ b/strings/6AB8A55E @@ -0,0 +1,3 @@ +$B86A + LDA $5E + +Fragment of address of well known floating point function and a load from zero page diff --git a/strings/856660A5 b/strings/856660A5 new file mode 100644 index 00000000..cf0c8513 --- /dev/null +++ b/strings/856660A5 @@ -0,0 +1,3 @@ +STA $66 + RTS + LDA fragment + +Store to well known zero page location + fragment diff --git a/strings/8570A565 b/strings/8570A565 new file mode 100644 index 00000000..cb06b4b6 --- /dev/null +++ b/strings/8570A565 @@ -0,0 +1,3 @@ +STA $70 + LDA $65 + +Store to well known zero page variable and load from another diff --git a/strings/C92DD004 b/strings/C92DD004 new file mode 100644 index 00000000..3f908040 --- /dev/null +++ b/strings/C92DD004 @@ -0,0 +1,3 @@ +CMP #$2D + BNE $04 + +Compare with ASCII minus and branch diff --git a/strings/C9309004C93C90 b/strings/C9309004C93C90 new file mode 100644 index 00000000..05f56458 --- /dev/null +++ b/strings/C9309004C93C90 @@ -0,0 +1,3 @@ +CMP #$30 + BCC $04 + CMP #$3C + BCC fragment + +Comparisons of some ASCII values diff --git a/strings/D0F9A567 b/strings/D0F9A567 new file mode 100644 index 00000000..5b5976c6 --- /dev/null +++ b/strings/D0F9A567 @@ -0,0 +1,3 @@ +BNE $F9 + LDA $67 + +Loop fragment + load from zero page diff --git a/testsuite/unit/math.vs b/testsuite/unit/math.vs index 8418b6c8..5b77cb2c 100644 --- a/testsuite/unit/math.vs +++ b/testsuite/unit/math.vs @@ -382,5 +382,123 @@ print "COMPARE" compare $62 $65 $1001 print "END" +print "TEST: FIN 1" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $501 31 00 +r A=$31 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 81 80 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + + +print "TEST: FIN 17" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $502 31 37 00 +r A=$31 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 85 88 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN +17" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $503 2B 31 37 00 +r A=$2B +r FL=$21 +r PC=$BCF3 +ret +fill $1001 $1006 85 88 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN -17" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $503 2D 31 37 00 +r A=$2D +r FL=$21 +r PC=$BCF3 +ret +fill $1001 $1006 85 88 00 00 00 FF +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN 20E1" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $504 32 30 45 31 00 +r A=$32 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 88 C8 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN 20.0E1" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $506 32 30 2E 30 45 31 00 +r A=$32 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 88 C8 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN 20.0E+1" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $507 32 30 2E 30 45 2B 31 00 +r A=$32 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 88 C8 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN 200E-1" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $507 32 30 30 45 2D 31 00 +r A=$32 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1006 88 C8 00 00 00 00 +print "COMPARE" +compare $61 $66 $1001 +print "END" + +print "TEST: FIN 123E-100" +fill $61 $66 FF FF FF FF FF CC +fill $7A $7B $00 $05 +fill $500 $509 31 32 33 45 2D 31 30 30 00 +r A=$32 +r FL=$20 +r PC=$BCF3 +ret +fill $1001 $1001 00 +print "COMPARE" +compare $61 $61 $1001 +print "END" + q