153 lines
3.0 KiB
ArmAsm
153 lines
3.0 KiB
ArmAsm
;; #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
|
|
}
|