Update FIN
This commit is contained in:
1 parent
1b1d0c4329
commit
1ec43e8cd7
7 files changed
+178
-169
No files matched your search
@@ -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 |
|
| `$BC9B` | `QINT` | DONE | From the Microsoft BASIC, original name: QINT |
|
||||||
| `$BCCC` | `int_FAC1` | DONE | From the Microsoft BASIC, original name: INT |
|
| `$BCCC` | `int_FAC1` | DONE | From the Microsoft BASIC, original name: INT |
|
||||||
| `$BCE9` | `clear_FAC1` | DONE | From the Microsoft BASIC, original name: CLRFAC |
|
| `$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 |
|
| `$BD7E` | `FINLOG` | DONE | From the Microsoft BASIC, original name: FINLOG |
|
||||||
| `$BDDD` | `FOUT` | DONE | From the Microsoft BASIC, original name: FOUT |
|
| `$BDDD` | `FOUT` | DONE | From the Microsoft BASIC, original name: FOUT |
|
||||||
| `$BF71` | `sqr_FAC1` | DONE | From the Microsoft BASIC, original name: SQR |
|
| `$BF71` | `sqr_FAC1` | DONE | From the Microsoft BASIC, original name: SQR |
|
||||||
|
|||||||
@@ -63,6 +63,8 @@
|
|||||||
!addr TEMPF2 = $5C ; $5C-$60 BASIC numeric work area
|
!addr TEMPF2 = $5C ; $5C-$60 BASIC numeric work area
|
||||||
!addr DECCNT = $5D ; Number of digits after decimal point
|
!addr DECCNT = $5D ; Number of digits after decimal point
|
||||||
!addr TENEXP = $5E ; Exponent count
|
!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 = $61 ; $61-$66 floating point accumulator 1
|
||||||
!addr FAC1_exponent = $61
|
!addr FAC1_exponent = $61
|
||||||
!addr FAC1_mantissa = $62 ; $62 - $65
|
!addr FAC1_mantissa = $62 ; $62 - $65
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
@@ -20,7 +20,7 @@ int matches[MAX_SIZE];
|
|||||||
|
|
||||||
int phase_mask[MAX_SIZE+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
|
// Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC
|
||||||
unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
|
unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
|
||||||
0xAEA8, 0xAEAC,
|
0xAEA8, 0xAEAC,
|
||||||
@@ -29,9 +29,7 @@ unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = {
|
|||||||
0xB391, 0xB39D,
|
0xB391, 0xB39D,
|
||||||
0xB3A2, 0xB3A5,
|
0xB3A2, 0xB3A5,
|
||||||
0xB849, 0xB97D,
|
0xB849, 0xB97D,
|
||||||
0xB983, 0xBCF2,
|
0xB983, 0xBDC1,
|
||||||
0xBD7E, 0xBD90,
|
|
||||||
0xBDB3, 0xBDC1,
|
|
||||||
0xBDDD, 0xBF51,
|
0xBDDD, 0xBF51,
|
||||||
0xBF71, 0xBF7A,
|
0xBF71, 0xBF7A,
|
||||||
0xBFB4, 0xBFEC,
|
0xBFB4, 0xBFEC,
|
||||||
|
|||||||
Reference in new issue
Block a user