work on parsing numbers from strings.

This commit is contained in:
Paul Gardner-Stephen committed 2019-04-27 22:03:04 +09:30
1 parent 8cb5e7e7c5
commit b1655ac7a9
3 files changed
+229

No files matched your search

+20
View File
@@ -8,6 +8,26 @@
.alias tokenise_work4 $F
.alias temp_string_ptr $35
.alias load_or_verify_or_tokenise_work5 $C
.alias basic_work22 $22
.alias basic_work23 $23
.alias basic_work24 $24
.alias basic_work25 $25
.alias basic_numeric_work_area $57 ; $57 - $60 inclusive = 10 bytes
;; Floating point accumulator 1 $61 - $68
.alias basic_fac1_exponent $61
.alias basic_fac1_mantissa $62 ; $62 - $65
.alias basic_fac1_sign $66
.alias basic_fac1_overflow $68
.alias basic_fac1_mantissa_lob $70
.alias basic_fac2_exponent $69
.alias basic_fac2_mantissa $6A ; $6A - $6D
.alias basic_fac2_sign $6E
.alias TXTTAB $2B
.alias IOSTATUS $90
+98
View File
@@ -0,0 +1,98 @@
;; Multiply Floating Point Accumulator by 10
;; = 8x + 2x
;; Implement by shifting MAC left one bit,
;; and then keeping that value to add on after
;; shifting two more bits left.
;; This should be done using basic_fac1_overflow to
;; hold the overflow bits, so that the result can
;; be exponent adjusted after, if required.
fac1_mul10:
lda #$00
sta basic_fac1_overflow
;; Multiply mantissa by 2
jsr fac1_mantissa_mul2
;; copy down to BASIC numeric work area at $57
;; (basic_numeric_work_area)
;; (We copy all 7 bytes off the FAC1, so that we have
;; the overflow bits, and the copy is as small as possible)
ldx #7
f1m10_l1:
lda basic_fac1_mantissa,x
sta basic_numeric_work_area,x
dex
bpl f1m10_l1
;; Multiply mantissa by 4, so it is now 8x original
jsr fac1_mantissa_mul2
jsr fac1_mantissa_mul2
;; Now add stored value of 2x to it, to get the total x10
ldy #3
ldx #0
clc
f1m10_l2:
lda basic_fac1_mantissa,x
adc basic_numeric_work_area,x
sta basic_fac1_mantissa,x
inx
dey
bpl f1m10_l2
lda basic_fac1_overflow
adc basic_numeric_work_area+7
sta basic_fac1_overflow
;; Now shift right and increase exponent until overflow
;; bits = $00
f1m10_l3:
lda basic_fac1_overflow
bne +
;; All done, return
clc
rts
;; Divide mantissa by two, and increment exponent
jsr fac1_mantissa_div2
inc basic_fac1_exponent
lda basic_fac1_exponent
bpl f1m10_l3
;; Exponent has bit 7 set, so has wrapped.
;; = OVERFLOW ERROR
lda #14
jmp do_basic_error
fac1_mantissa_mul2:
ldy #3
ldx #0
clc
f1m1_l1:
;; Multiply mantissa by 2, and store overflow
;; in basic_fac1_bits
lda basic_fac1_mantissa,x
rol
sta basic_fac1_mantissa,x
inx
dey
bpl f1m1_l1
lda basic_fac1_overflow
rol
sta basic_fac1_overflow
rts
fac1_mantissa_div2:
;; Divide mantissa by 2, including using overflow bits
clc
lda basic_fac1_overflow
ror
sta basic_fac1_overflow
ldy #3
f1md2_l1:
lda basic_fac1_mantissa,y
ror
sta basic_fac1_mantissa,y
dey
bpl f1md2_l1
rts
+111
View File
@@ -0,0 +1,111 @@
;; Parse a number from the input buffer at $0200+tokenise_work1
;; Result is put into FAC1.
;; tokenise_work1 is updated with first position after the number.
;; XXX - Remember decimal position and exponent, and apply them
;; after to produce normalised floating point number.
ij_not_a_digit:
;; XXX check for ".", "E", "+" and "-"
;; Other chars terminate the accumulation.
CLC
RTS
inject_number:
;; Clear FAC1
jsr erase_fac1
;; Clear decimal position flag
lda #$ff
sta tokenise_work2
;; Check if leading char is a - sign
;; Note: the - will have been tokenised to $AB
;; XXX - implement
ij_loop1:
ldx tokenise_work1
lda $0200,x
cmp #$30
bcc ij_not_a_digit
cmp #$39
bcs ij_not_a_digit
;; It is a digit
;; Only add digit if we have not overflowed the accuracy of
;; the mantissa
lda basic_fac1_exponent
beq ij_accept_precision
;; We have an extra digit after saturating our precision.
;; Thus we should ignore the digit, and just multiply the FAC
;; by 10, but only if we have not seen a decimal point.
;; If we have seen a decimal point, then we can completely ignore
;; the digit, as it is contributing not recordable information
lda tokenise_work2
cmp #$ff
bne ij_seen_decimal_point
jsr fac1_mul10
;; Fall through
ij_seen_decimal_point:
jmp ij_consider_next_digit
ij_accept_precision:
;; We can accept more precision, so multiply the mantissa by 10, so that
;; we can add the new digit in
jsr fac1_mul10
lda basic_fac1_exponent
bne ij_consider_next_digit
;; Get digit
ldx tokenise_work1
lda $0200,x
sec
sbc #$30
;; Add to FAC1 mantissa
clc
adc basic_fac1_mantissa+0
sta basic_fac1_mantissa+0
ldx #1
ldy #3
ij_loop2:
lda basic_fac1_mantissa,x
adc #$00
sta basic_fac1_mantissa+1,x
inx
dey
bne ij_loop2
bcc +
;; Carry set, so we have overflowed.
;; We should shift everything right one digit, and increase
;; the exponent by one. The non-zero exponent tells us that we
;; can't fit any more precision in.
jsr fac1_mantissa_div2
*
ij_consider_next_digit:
;; Consider next digit
inc tokenise_work1
jmp ij_loop1
rts
erase_fac1:
lda #$00
ldx #7
*
sta basic_fac1_exponent,x
dex
bpl -
sta basic_fac1_mantissa_lob
rts