/
polygon.s
319 lines (249 loc) · 4.66 KB
/
polygon.s
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
.include "MACROSv21.s"
.eqv NUMCOLUNAS 320
.eqv NUMLINHAS 240
.data
window_dimensions: .word 1280 720
radius: .word 0 # will be replaced by window_dimensions[1] * 4 / 9 in `main`
lados: .word 5
tau: .float 6.284
dx: .float 0.02
to_radians: .float 0.01745329251
V: .space 404 # máximo de 50 vértices
.text
main:
# radius = NUMLINHAS * 4 / 9
li t0 NUMLINHAS
slli t0 t0 2 # t0 *= 4
li t1 9
div t0 t0 t1 # t0 /= 9
la t1 radius
sw t0 0(t1)
lw a0 radius
li s0 0 # frame
li s1 0 # angulo
main.loop:
li a0 0x00
mv a1 s0
li a7 48 # clear screen
ecall
# Check if the user wants to change the number of sides
jal check_input
# Circunferencia:
la t0 radius
lw a0 0(t0)
li a1 0
li a2 36 # polígono de 36 lados = circunferencia
jal vertices
li a1 0x07
mv a2 s0
jal desenha
# Poligono:
la t0 radius
lw a0 0(t0) # radius
mv a1 s1 # angulo
la t0 lados
lw a2 0(t0)
jal vertices
li a1 0xf8
mv a2 s0
jal desenha
# Muda de frame
li t0 0xFF200604
sb s0 0(t0)
xori s0 s0 1
addi s1 s1 1
li t0 360
bge s1 t0 main.fix_angle
jal stall
j main.loop
main.fix_angle:
sub s1 s1 t0
j main.loop
main.exit:
li a7 10
ecall
# a0 = radius
# a1 = angulo
# a2 = numero de lados
vertices:
addi sp sp -28
sw ra 0(sp)
sw s0 4(sp)
sw s1 8(sp)
fsw fs0 12(sp)
fsw fs1 16(sp)
fsw fs2 20(sp)
fsw fs3 24(sp)
fcvt.s.w fs0 a0 # fs0 = radius
neg a1 a1
fcvt.s.w fs1 a1 # fs1 = angulo
la t0 to_radians
flw ft0 0(t0)
fmul.s fs1 fs1 ft0
mv s0 a2 # s0 = numero de lados
la t0 tau
flw fs2 0(t0)
fcvt.s.w ft0 s0
fdiv.s fs2 fs2 ft0 # fs2 = incremento do angulo a cada passo
la s1 V # output
sw s0 0(s1) # salva o número de lados na primeira word de V
addi s1 s1 4
vertices.loop:
blez s0 vertices.exit
fmv.s fa0 fs1
li a0 1
jal sin
fmv.s fs3 fa0 # fs3 = sin(theta)
fmv.s fa0 fs1
li a0 0
jal sin # cos
# Multiply by the radius
fmul.s fs3 fs3 fs0
fmul.s fa0 fa0 fs0
# Converte para inteiro (x = t0, y = t1)
fcvt.w.s t0 fa0
fcvt.w.s t1 fs3
# Translada para o centro
li t2 NUMCOLUNAS
srli t2 t2 1
add t0 t0 t2
li t2 NUMLINHAS
srli t2 t2 1
add t1 t1 t2
# Salva em V
sw t0 0(s1)
sw t1 4(s1)
addi s1 s1 8
fadd.s fs1 fs1 fs2
addi s0 s0 -1
j vertices.loop
vertices.exit:
lw ra 0(sp)
lw s0 4(sp)
lw s1 8(sp)
flw fs0 12(sp)
flw fs1 16(sp)
flw fs2 20(sp)
flw fs3 24(sp)
addi sp sp 28
la a0 V
ret
# a0 = int* V
# a1 = cor
# a2 = frame
desenha:
mv t0 a0
mv t6 a1
mv t5 a2
lw t1 0(t0) # t1 = numero de lados
# Desenha V[n-1] -> V[0]
slli a0 t1 3
add a0 a0 t0
lw a1 0(a0)
lw a0 -4(a0)
lw a2 4(t0)
lw a3 8(t0)
mv a4 t6
mv a5 t5
li a7 47
ecall
addi t1 t1 -1
addi t0 t0 12
desenha.loop:
blez t1 desenha.exit
lw a0 -8(t0)
lw a1 -4(t0)
lw a2 0(t0)
lw a3 4(t0)
mv a4 t6
mv a5 t5
li a7 47
ecall
addi t0 t0 8
addi t1 t1 -1
j desenha.loop
desenha.exit:
ret
# fa0 = theta
# a0 = 1 para sin(x), 0 para cos(x)
sin:
fmv.s.x ft0 x0
fadd.s fa1 fa0 ft0 # fa1 = theta
fadd.s fa0 ft0 ft0 # fa0 = resposta
fadd.s fa2 fa1 ft0 # fa2 = pow(theta, 2n + 1)
li t0 1
fcvt.s.w fa3 t0 # fa3 = (2n + 1)!
bnez a0 sin.notcos # just sin(x)
sin.cos: # yup
fmv.s fa2 fa3 # pow(theta, 2n=0) = 1
sin.notcos:
mv t0 x0
sin.loop:
li t1 10 # executa 11 vezes /shrug
bgt t0 t1 sin.exit
fdiv.s ft1 fa2 fa3
andi t1 t0 1
bnez t1 sin.sub # n é ímpar
sin.sum:
fadd.s fa0 fa0 ft1
j sin.control
sin.sub:
fsub.s fa0 fa0 ft1
sin.control:
# atualiza pow(theta, 2n+1)
fmul.s fa2 fa2 fa1
fmul.s fa2 fa2 fa1
beqz a0 sin.cos.control # cos(x) control
# atualiza (2n + 1)!
addi t0 t0 1
# vezes 2, 4, 6, ...
slli t1 t0 1
fcvt.s.w ft1 t1
fmul.s fa3 fa3 ft1
# vezes 3, 5, 7, ...
addi t1 t1 1
fcvt.s.w ft1 t1
fmul.s fa3 fa3 ft1
j sin.loop
sin.cos.control:
# atualiza (2n)!
# vezes 1, 3, 5, ...
slli t1 t0 1
addi t1 t1 1
fcvt.s.w ft1 t1
fmul.s fa3 fa3 ft1
# vezes 2, 4, 6, ...
addi t1 t1 1
fcvt.s.w ft1 t1
fmul.s fa3 fa3 ft1
addi t0 t0 1
j sin.loop
sin.exit:
ret
check_input:
li t0 0xff200000
lb a0 0(t0)
andi a0 a0 1
beqz a0 check_input.exit
lb a0 4(t0)
li a1 '0'
sub a0 a0 a1
# Make sure the number is at least 2
li a1 2
blt a0 a1 check_input.exit
la t0 lados
sw a0 0(t0)
check_input.exit:
ret
# busy sleep for 8ms
stall:
li t0 8
csrr a0 time
stall.loop:
csrr a1 time
sub a1 a1 a0
bge a1 t0 stall.exit
j stall.loop
stall.exit:
ret
.include "SYSTEMv21.s"