-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathmult84.a
More file actions
164 lines (143 loc) · 2.68 KB
/
mult84.a
File metadata and controls
164 lines (143 loc) · 2.68 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
; mult84.a
; based on the 8 bit multiply of mult65.a
; then adjusted for 16 bit multiplication by TobyLobster
;
; 16 bit x 16 bit unsigned multiply, 32 bit result
; Average cycles: 253.92
; 1199 bytes
inputA = $02 ; 2 bytes (a0,a1)
inputB = $04 ; 2 bytes (b0,b1)
result = $06 ; 4 bytes
lmul0 = $0a ; address of square table low (2 bytes)
lmul1 = $0c ; address of square table high (2 bytes)
* = $0200
; Tables must be aligned with page boundary
sqrLow
!for i, 0, 511 {
!byte <((i*i)/4)
}
sqrHigh
!for i, 0, 511 {
!byte >((i*i)/4)
}
; ***************************************************************************************
;
; 16 bit x 16 bit unsigned multiply, 32 bit result
;
; make sure to call 'jsr mult_init' (once only) before using this multiply
;
; On Entry:
; inputA: multiplier (2 bytes)
; inputB: multiplicand (2 bytes)
;
; On Exit:
; result: product (4 bytes)
mult
; (a0*b0)
ldy inputA
ldx inputB
stx lmul0
stx lmul1
tya
sec
sbc lmul0
bcs +
sbc #0 ; negate A
eor #$ff
+
tax
lda (lmul0),y
sbc sqrLow,x
sta result ; low byte
lda (lmul1),y
sbc sqrHigh,x
sta result+1 ; high byte
; (a1*b0)
ldy inputA+1
ldx inputB
tya
sec
sbc lmul0
bcs +
sbc #0 ; negate A
eor #$ff
+
tax
lda (lmul0),y
sbc sqrLow,x
sta temp1
lda (lmul1),y
sbc sqrHigh,x
sta result+2
temp1 = *+1
lda #0
clc
adc result+1
sta result+1
bcc +
inc result+2
+
;(a0*b1)
ldy inputA
ldx inputB+1
stx lmul0
stx lmul1
tya
sec
sbc lmul0
bcs +
sbc #0 ; negate A
eor #$ff
+
tax
lda (lmul0),y
sbc sqrLow,x
sta temp2
lda (lmul1),y
sbc sqrHigh,x
tax
temp2 = *+1
lda #0
clc
adc result+1
sta result+1
txa
adc result+2
sta result+2
lda #0
rol ; remember the carry for result+3
sta result+3
; (a1*b1)
ldy inputA+1
ldx inputB+1
tya
sec
sbc lmul0
bcs +
sbc #0 ; negate A
eor #$ff
+
tax
lda (lmul0),y
sbc sqrLow,x
sta temp3
lda (lmul1),y
sbc sqrHigh,x
tax
temp3 = *+1
lda #0
clc
adc result+2
sta result+2
txa
adc result+3
sta result+3
rts
; ***************************************************************************************
; call this once to initialise high bytes of pointers to table
mult_init
lda #>sqrLow ; high byte (#2 in this instance)
sta lmul0+1
lda #>sqrHigh ; high byte (#4 in this instance)
sta lmul1+1
rts