-
Notifications
You must be signed in to change notification settings - Fork 4
/
sqrt18.a
115 lines (105 loc) · 3.85 KB
/
sqrt18.a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
; https://github.com/TobyLobster/sqrt_test/blob/main/sqrt/sqrt18.a
input = $02 ; two byte input value
temp = $04 ; one byte temporary value
* = $0200 ;
sqrt
lda input+1 ;
beq less_than_256 ;
cmp #4 ;
bcc less_than_1024 ;
normal_root
lsr ;
lsr ;
tax ; X = input // 1024
lda input ;
sec ;
sbc sqlow,x ;
sta input ;
lda input+1 ;
sbc sqhigh,x ;
sta input+1 ; input -= sq[Y]
lda lower_bound_sqrt,x ; Y = lower_bound_sqrt[X]
continue
tay ;
asl ;
tax ; X = temp = 2*y
lda #0 ;
rol ;
sta temp1 ; temp1 is zero or one
sec ;
loop
inx ; temp += 1
stx temp ;
lda input ;
sbc temp ; carry is always set
sta input ; input -= temp
lda input+1 ;
temp1 = * + 1
sbc #0 ; self modifying code
bcc finished ; branch if we fall below zero
sta input+1 ;
iny ; root += 1
inx ; temp += 1
bne loop ; ALWAYS branch
finished
tya ;
rts ; A = root
; The rest is to bring the worst case down.
less_than_256
ldx input
beq done
cpx #16
bcc less_than_16
less_than_1024
; isqrt(input) = isqrt(64*input)/8
lsr ; multiply by 64
ror input ;
ror ;
ror input ;
ror ;
ldx input ;
sta input ;
stx input+1 ;
txa ;
jsr normal_root ; take the root
lsr ; divide by 8
lsr ;
lsr ;
done
rts ;
less_than_16
lda #1 ; smaller than a table lookup
cpx #4 ;
bcc done ;
lda #2 ;
cpx #9 ;
bcc done ;
lda #3 ;
rts ;
lower_bound_sqrt
!byte $00, $20, $2d, $37, $40, $47, $4e, $54
!byte $5a, $60, $65, $6a, $6e, $73, $77, $7b
!byte $80, $83, $87, $8b, $8f, $92, $96, $99
!byte $9c, $a0, $a3, $a6, $a9, $ac, $af, $b2
!byte $b5, $b7, $ba, $bd, $c0, $c2, $c5, $c7
!byte $ca, $cc, $cf, $d1, $d4, $d6, $d9, $db
!byte $dd, $e0, $e2, $e4, $e6, $e8, $eb, $ed
!byte $ef, $f1, $f3, $f5, $f7, $f9, $fb, $fd
sqlow
!byte $00, $00, $e9, $d1, $00, $b1, $c4, $90
!byte $a4, $00, $d9, $e4, $44, $a9, $51, $19
!byte $00, $09, $31, $79, $e1, $44, $e4, $71
!byte $10, $00, $c9, $a4, $91, $90, $a1, $c4
!byte $f9, $d1, $24, $89, $00, $04, $99, $b1
!byte $64, $90, $61, $a1, $90, $e4, $f1, $59
!byte $c9, $00, $84, $10, $a4, $40, $b9, $69
!byte $21, $e1, $a9, $79, $51, $31, $19, $09
sqhigh
!byte $00, $04, $07, $0b, $10, $13, $17, $1b
!byte $1f, $24, $27, $2b, $2f, $33, $37, $3b
!byte $40, $43, $47, $4b, $4f, $53, $57, $5b
!byte $5f, $64, $67, $6b, $6f, $73, $77, $7b
!byte $7f, $82, $87, $8b, $90, $93, $97, $9a
!byte $9f, $a2, $a7, $aa, $af, $b2, $b7, $bb
!byte $be, $c4, $c7, $cb, $ce, $d2, $d7, $db
!byte $df, $e2, $e6, $ea, $ee, $f2, $f6, $fa