Update FIN

This commit is contained in:
Rikard Nordgren authored and FeralChild64 committed 2026-05-09 17:01:44 +02:00
1 parent 1b1d0c4329
commit 1ec43e8cd7
7 files changed
+178 -169

No files matched your search

+1 -1
View File
@@ -248,7 +248,7 @@ Floating point mathematical routines - not official, but well known and broadly
| `$BC9B` | `QINT` | DONE | From the Microsoft BASIC, original name: QINT |
| `$BCCC` | `int_FAC1` | DONE | From the Microsoft BASIC, original name: INT |
| `$BCE9` | `clear_FAC1` | DONE | From the Microsoft BASIC, original name: CLRFAC |
| `$BCF3` | `FIN` | PARTIAL | Only for 38k memory model + not fully tested yet |
| `$BCF3` | `FIN` | DOME | From the Microsoft BASIC Only for 38k memory model |
| `$BD7E` | `FINLOG` | DONE | From the Microsoft BASIC, original name: FINLOG |
| `$BDDD` | `FOUT` | DONE | From the Microsoft BASIC, original name: FOUT |
| `$BF71` | `sqr_FAC1` | DONE | From the Microsoft BASIC, original name: SQR |
+2
View File
@@ -63,6 +63,8 @@
!addr TEMPF2 = $5C ; $5C-$60 BASIC numeric work area
!addr DECCNT = $5D ; Number of digits after decimal point
!addr TENEXP = $5E ; Exponent count
!addr DPTFLG = $5F ; Decimal point flag for FIN
!addr EXPSGN = $60 ; Exponent sign for FIN
!addr __FAC1 = $61 ; $61-$66 floating point accumulator 1
!addr FAC1_exponent = $61
!addr FAC1_mantissa = $62 ; $62 - $65
-152
View File
@@ -1,152 +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
;
!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
lda FIN_DIGIT
jsr FINLOG
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
}
-12
View File
@@ -1,12 +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
!ifdef CONFIG_MEMORY_MODEL_38K {
jmp FIN
} else {
+STUB_IMPLEMENTATION
}
+130
View File
@@ -0,0 +1,130 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
; This file is under the MIT license, it contains code released by Microsoft Corporation.
; See LICENSE for more information.
; Math package - imports string to FAC1, ignores spaces
;
; This is verified to be identical to the original Microsoft implementation where it was named FIN.
;
; 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
;
; NUMBER INPUT IS LEFT IN FAC.
; AT ENTRY [TXTPTR] POINTS TO THE FIRST CHARACTER IN A TEXT BUFFER.
; THE FIRST CHARACTER IS ALSO IN ACCA. FIN PACKS THE DIGITS
; INTO THE FAC AS AN INTEGER AND KEEPS TRACK OF WHERE THE
; DECIMAL POINT IS. [DPTFLG] TELL WHETHER A DP HAS BEEN
; SEEN. [DECCNT] IS THE NUMBER OF DIGITS AFTER THE DP.
; AT THE END [DECCNT] AND THE EXPONENT ARE USED TO
; DETERMINE HOW MANY TIMES TO MULTIPLY OR DIVIDE BY TEN
; TO GET THE CORRECT NUMBER.
!ifdef CONFIG_MEMORY_MODEL_38K {
FIN:
ldy #0 ; Zero FAC1_sign and SGNFLG
ldx #10 ; Zero exp and hi bytes
FINZLP:
sty DECCNT,X ; Zero low bytes
dex ; Zero TENEXP and EXPSGN
bpl FINZLP ; Zero DECCNT, DPTFLG
bcc FINDGQ ; Flags still set from CHRGET
cmp #'-' ; A negative sign?
bne QPLUS ; No, try plus sign
stx SGNFLG ; It's negative
beq FINC ; Always branches
QPLUS:
cmp #'+' ; Plus sign?
bne FIN1 ; Yes, skip it
FINC:
jsr CHRGET
FINDGQ:
bcc FINDIG
FIN1:
cmp #'.' ; The decimal point?
beq FINDP ; No kidding
cmp #'E' ; Exponent follows
bne FINE ; No
;HERE TO CHECK FOR SIGN OF EXP.
jsr CHRGET ; Yes, Get another
bcc FNEDG1 ; It is a digit. (Easier than backing up pointer)
cmp #$AB ; Minus with sign set (from table)
beq FINEC1 ; Negate
cmp #'-' ; Minus sign?
beq FINEC1
cmp #$AA ; Plus with sign set (from table)
beq FINEC
cmp #'+' ; Plus sign?
beq FINEC
bne FINEC2
FINEC1:
ror EXPSGN ; Turn it on
FINEC:
jsr CHRGET ; Get another
FNEDG1:
bcc FINEDG ; It is a digit
FINEC2:
bit EXPSGN
bpl FINE
lda #0
sec
sbc TENEXP
jmp FINE1
FINDP:
ror DPTFLG
bit DPTFLG
bvc FINC
FINE:
lda TENEXP
FINE1:
sec
sbc DECCNT ; Get number of places to shift
sta TENEXP
beq FINQNG ; Negate?
bpl FINMUL ; Positive so multiply
FINDIV:
jsr div10_FAC1_p
inc TENEXP ; Done?
bne FINDIV ; No
beq FINQNG ; Yes
FINMUL:
jsr mul10_FAC1
dec TENEXP ; Done
bne FINMUL ; No
FINQNG:
lda SGNFLG
bmi NEGXQS ; If positive, Return
rts
NEGXQS:
jmp toggle_sign_FAC1 ; Otherwise, negate and return
FINDIG:
pha
bit DPTFLG
bpl FINDG1
inc DECCNT
FINDG1:
jsr mul10_FAC1
pla ; Get it back
sec
sbc #'0'
jsr FINLOG ; Add it in
jmp FINC
} else {
+STUB_IMPLEMENTATION
}
+43
View File
@@ -0,0 +1,43 @@
;; #LAYOUT# STD * #TAKE
;; #LAYOUT# X16 BASIC_0 #TAKE-OFFSET 2000
;; #LAYOUT# * BASIC_0 #TAKE
;; #LAYOUT# * * #IGNORE
; This file is under the MIT license, it contains code released by Microsoft Corporation.
; See LICENSE for more information.
; Math package - add an ASCII digit in A that has been converted to a signed integer to FAC1
;
; This is verified to be identical to the original Microsoft implementation where it was named FINEDG.
;
; HERE PACK IN THE NEXT DIGIT OF THE EXPONENT.
; MULTIPLY THE OLD EXP BY 10 AND ADD IN THE NEXT
; DIGIT. NOTE: EXP OVERFLOW IS NOT CHECKED FOR.
!ifdef CONFIG_MEMORY_MODEL_38K {
FINEDG:
lda TENEXP ; Get exp so far
cmp #10 ; Will result be >= 100
bcc MLEX10
lda #100 ; Get 100
bit EXPSGN
bmi MLEXMI ; If neg exp, no check for overflow
jmp overflow_error
MLEX10:
asl ; Mult by 2 twice
asl
clc ; Possible shift out of high
adc TENEXP ; Like multiplying by five
asl ; And now by ten
clc
ldy #0
adc (TXTPTR),Y
sec
sbc #'0'
MLEXMI:
sta TENEXP ; Save result
jmp FINEC
}
+2 -4
View File
@@ -20,7 +20,7 @@ int matches[MAX_SIZE];
int phase_mask[MAX_SIZE+MAX_SIZE];
#define NUM_CHUNKS 15
#define NUM_CHUNKS 13
// Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC
unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
0xAEA8, 0xAEAC,
@@ -29,9 +29,7 @@ unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
0xB391, 0xB39D,
0xB3A2, 0xB3A5,
0xB849, 0xB97D,
0xB983, 0xBCF2,
0xBD7E, 0xBD90,
0xBDB3, 0xBDC1,
0xB983, 0xBDC1,
0xBDDD, 0xBF51,
0xBF71, 0xBF7A,
0xBFB4, 0xBFEC,