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 |
|
||||
| `$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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
#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,
|
||||
|
||||
Reference in new issue
Block a user