-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfindmax.asm
299 lines (256 loc) · 5.94 KB
/
findmax.asm
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
#include p18f87k22.inc
global find_max, q1_H, q2_H, q3_H, q4_H, q1_L, q2_L, q3_L, q4_L
global current_max_H, q_max_H, q_max_L
acs0 udata_acs ; named variables in access ram
current_H res 1 ; current iterator of q_H
current_max_H res 1 ; current index of max q_H
candidate_max_H res 1
candidate_L res 1
neg_count res 1
neg_tmp res 1
q1_H res 1
q2_H res 1
q3_H res 1
q4_H res 1
q1_L res 1
q2_L res 1
q3_L res 1
q4_L res 1
q_max_H res 1
q_max_L res 1
findmax code
find_max
setup
call handle_negs
movlw 0x00
movwf candidate_L
movwf current_H
movwf current_max_H
movlb 3
lfsr FSR0, 0x300
movlb 3
lfsr FSR1, 0x340
movff q1_H, POSTINC0
movff q2_H, POSTINC0
movff q3_H, POSTINC0
movff q4_H, POSTINC0
movff q1_L, POSTINC1
movff q2_L, POSTINC1
movff q3_L, POSTINC1
movff q4_L, POSTINC1
movlb 3
lfsr FSR0, 0x300
movlb 3
lfsr FSR1, 0x340
start_
movff POSTINC0, q_max_H ; Loads q1 into q_max_H
compare_next
movf POSTINC0, W ; Temp storage for candidate q
incf current_H ; Increments current_H
cpfsgt q_max_H ; Compare if W < max_q_H
bra check_greater_equal ; if >= do not skip check for ==
rejoin_H
movlw 0x03
cpfseq current_H ; if counter_H == 3
bra compare_next ; Check next number
goto exit
check_greater_equal
cpfseq q_max_H ; compare if W == max_q_H
bra set_max ; since != and previously !< , must be >
movff current_H, candidate_max_H
call check_low ; since == then need to check low bits
goto rejoin_H ; Rejoins main loop
set_max
movwf q_max_H
movff current_H, current_max_H
goto rejoin_H ; Rejoins main loop
check_low
movf current_max_H, W
movff PLUSW1, q_max_L ; Loads q1 into q_max_H
compare_L
movf candidate_max_H, W
movff PLUSW1, candidate_L
movf candidate_L, W
cpfsgt q_max_L ; compare if max_q_H > W
movwf q_max_L ; if q_max_L < set new max
; else if q_max_L already > W, do nothing
cpfsgt q_max_L ; compare if max_q_H > W
movff candidate_max_H, current_max_H
return
exit
movlb 3
lfsr FSR0, 0x300
movlb 3
lfsr FSR1, 0x340
movf current_max_H, W
movff PLUSW0, q_max_H
movff PLUSW1, q_max_L
movlw 0x00
cpfseq neg_count
bra handle_invert_back
bra final
handle_invert_back
movlw 0x04
cpfseq neg_count
bra sub_one
goto invert_neg_back
sub_one
call sub_one_back
final
return
; *** Count number of negative numbers and handle the three different *** ;
; *** cases: *** ;
; *** 1. All four numbers are positive *** ;
; *** 2. Some numbers are positive, some are negative *** ;
; *** 3. All numbers are negative *** ;
handle_negs
call count_negs
call check_negs
return
count_negs
clrf neg_count
movlw 0x80
cpfslt q1_H
incf neg_count
movlw 0x80
cpfslt q2_H
incf neg_count
movlw 0x80
cpfslt q3_H
incf neg_count
movlw 0x80
cpfslt q4_H
incf neg_count
return
; If neg_count = 0, situation 1. If neg_count = 4, situation 3. Else, it is
; situation 2 where some are negative
check_negs
movlw 0x00
cpfseq neg_count
bra check_all_neg
return
check_all_neg
movlw 0x04
cpfseq neg_count
bra check_some_negs
call invert_negs
return
check_some_negs
call handle_some_negs
return
invert_negs
movlw 0xFF
addwf q1_L, F
movlw 0xFF
addwfc q1_H, F
movlw 0xFF
addwf q2_L, F
movlw 0xFF
addwfc q2_H, F
movlw 0xFF
addwf q3_L, F
movlw 0xFF
addwfc q3_H, F
movlw 0xFF
addwf q4_L, F
movlw 0xFF
addwfc q4_H, F
return
invert_neg_back
movlw 0x01
addwf q_max_L, F
movlw 0x00
addwfc q_max_H, F
goto final
sub_one_back
movlw 0x01
subwf q_max_L, F
movlw 0x00
subwf q_max_H
return
; *** If number is negative, change to 0. If positive, add 1 to handle *** ;
; *** the case where positives are 0s e.g. 0, 0, 0, -1 -> 0, 0, 0, 0 *** ;
handle_some_negs
movlw 0x80
cpfslt q1_H
goto handle_q1_negative
call handle_q1_positive
check_q2
movlw 0x80
cpfslt q2_H
goto handle_q2_negative
call handle_q2_positive
check_q3
movlw 0x80
cpfslt q3_H
goto handle_q3_negative
call handle_q3_positive
check_q4
movlw 0x80
cpfslt q4_H
goto handle_q4_negative
call handle_q4_positive
rejoin
return
handle_q1_positive
movlw 0x01
addwf q1_L, F
movlw 0x00
addwfc q1_H, F
return
handle_q1_negative
clrf q1_H
clrf q1_L
goto check_q2
handle_q2_positive
movlw 0x01
addwf q2_L, F
movlw 0x00
addwfc q2_H, F
return
handle_q2_negative
clrf q2_H
clrf q2_L
goto check_q3
return
handle_q3_positive
movlw 0x01
addwf q3_L, F
movlw 0x00
addwfc q3_H, F
return
handle_q3_negative
clrf q3_H
clrf q3_L
goto check_q4
return
handle_q4_positive
movlw 0x01
addwf q4_L, F
movlw 0x00
addwfc q4_H, F
return
handle_q4_negative
clrf q4_H
clrf q4_L
goto rejoin
return
test_cases
movlw 0x00
movwf q1_H
movlw 0x00
movwf q1_L
movlw 0xFF
movwf q2_H
movlw 0xFD
movwf q2_L
movlw 0x00
movwf q3_H
movlw 0x00
movwf q3_L
movlw 0xFF
movwf q4_H
movlw 0xFE
movwf q4_L
return
end