digital_clock.s 8.01 KB
Newer Older
1
.text
2
3
# FIXME: currently only displays that which has been updated.

4
5
main:
# initialisation of the month discrimination
6
# 0..0101011010101
7
8
  addi $s0, $zero, 2773
# TODO: change initialisation to input value (for example, linux time stamp)
9
10
11
12
13
14
15
16
  xor $s1, $s1, $s1 #day
  xor $s2, $s2, $s2 #month
  xor $fp, $fp, $fp #unit hour
  xor $sp, $sp, $sp #digit hour
  xor $t8, $t8, $t8 #unit minute
  xor $t9, $t9, $t9 #digit minute
  xor $k0, $k0, $k0 #unit second
  xor $k1, $k1, $k1 #digit second
17

18
19
# initialisation of the value counting the leap years and the month
# Format : mmmm.ccccc where m = month, c = counter
20
  xor $s4, $s4, $s4
21

Noémie Fong's avatar
Noémie Fong committed
22
# $s6 and $s7 will be used to store addresses for future jumps
23
# $t6 will be used to remember which values have already been printed
Noémie Fong's avatar
Noémie Fong committed
24
# $t7 will be used as a flag for when we are processing hours
25
26
27
  j clock

clock:
Noémie Fong's avatar
Noémie Fong committed
28
29
# We loop until a second has passed.
# Comment this part for performance tests.
Noémie Fong's avatar
Noémie Fong committed
30
31
32
#  li $v0, 5
#  syscall
#  beq $v0, $s5, clock
Noémie Fong's avatar
Noémie Fong committed
33
# We update the time.
Noémie Fong's avatar
Noémie Fong committed
34
#  add $s5, $zero, $v0
Noémie Fong's avatar
Noémie Fong committed
35
# We empty the buffer
Noémie Fong's avatar
Noémie Fong committed
36
  la $a0, end
Noémie Fong's avatar
Noémie Fong committed
37
38
39
  li $v0, 4
  syscall
# We now start the calculations for the next second.
Noémie Fong's avatar
Noémie Fong committed
40
  j seconds
41

Noémie Fong's avatar
Noémie Fong committed
42
print_zero:
Noémie Fong's avatar
Noémie Fong committed
43
  la $a0, zero
44
45
46
47
48
49
50
51
  addi $t0, $zero, 1
  xor $a1, $a1, $a1
  j print

print_zero_digit:
  la $a0, zero
  addi $t0, $zero, 1
  xor $a2, $a2, $a2
52
53
  j print

Noémie Fong's avatar
Noémie Fong committed
54
print_one:
Noémie Fong's avatar
Noémie Fong committed
55
  la $a0, one
56
57
  j print

Noémie Fong's avatar
Noémie Fong committed
58
print_two:
Noémie Fong's avatar
Noémie Fong committed
59
  la $a0, two
60
61
  j print

62

Noémie Fong's avatar
Noémie Fong committed
63
print_three:
Noémie Fong's avatar
Noémie Fong committed
64
  la $a0, three
65
66
  j print

Noémie Fong's avatar
Noémie Fong committed
67
print_four:
Noémie Fong's avatar
Noémie Fong committed
68
# HACK : $t7 = 2 when dealing with hours -> check if digit = 2
69
# We test whether this is the 4 of 24 hours. If so, jump to twenty_four
Noémie Fong's avatar
Noémie Fong committed
70
  and $t2, $t7, $a2
71
  bne $t2, $zero, print_twenty_four
Noémie Fong's avatar
Noémie Fong committed
72
  la $a0, four
73
74
  j print

75
76
77
78
79
80
81
# We handle the case of 24h, coming from the units.
print_twenty_four:
  xor $a1, $a1, $a1
  addi $t0, $zero, 1
  la $a0, zero
  j print

Noémie Fong's avatar
Noémie Fong committed
82
print_five:
Noémie Fong's avatar
Noémie Fong committed
83
  la $a0, five
84
85
  j print

Noémie Fong's avatar
Noémie Fong committed
86
print_six:
Noémie Fong's avatar
Noémie Fong committed
87
  la $a0, six
88
89
  j print

Noémie Fong's avatar
Noémie Fong committed
90
print_seven:
Noémie Fong's avatar
Noémie Fong committed
91
  la $a0, seven
92
93
  j print

Noémie Fong's avatar
Noémie Fong committed
94
print_eight:
Noémie Fong's avatar
Noémie Fong committed
95
  la $a0, eight
96
97
  j print

Noémie Fong's avatar
Noémie Fong committed
98
print_nine:
Noémie Fong's avatar
Noémie Fong committed
99
  la $a0, nine
100
101
  j print

Martin Pépin's avatar
Martin Pépin committed
102
print:
Noémie Fong's avatar
Noémie Fong committed
103
  li $v0, 4
104
105
106
  syscall
  jr $ra

107
108
# To make a conditional jump to $ra
break:
Martin Pépin's avatar
Martin Pépin committed
109
  jr $ra
110

Noémie Fong's avatar
Noémie Fong committed
111
# We use this block to compute the display of a unit - seconds, minutes or hours
112
113
114
115
unit:
  xor $t0, $t0, $t0
  xor $v0, $v0, $v0
# $t0 is a flag at 1 iff an update is needed
Noémie Fong's avatar
Noémie Fong committed
116
  addi $t1, $zero, 1
117
118
119
120
# We increment $a1
  addi $a1, $a1, 1
# We use $t0 as an easy way to access 0, but here $t0 = $zero
# We set the return adress to be the digit
Noémie Fong's avatar
Noémie Fong committed
121
  la $ra, digits
122
# We test the value of $a1
Noémie Fong's avatar
Noémie Fong committed
123
  beq $a1, $t1, print_one
124
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
125
  beq $a1, $t1, print_two
126
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
127
  beq $a1, $t1, print_three
128
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
129
  beq $a1, $t1, print_four
130
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
131
  beq $a1, $t1, print_five
132
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
133
  beq $a1, $t1, print_six
134
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
135
  beq $a1, $t1, print_seven
136
  addi $t1, $t1, 1
Noémie Fong's avatar
Noémie Fong committed
137
  beq $a1, $t1, print_eight
138
139
  addi $t1, $t1, 1
  beq $a1, $t1, print_nine
Noémie Fong's avatar
Noémie Fong committed
140
  addi $t1, $t1, 1
141
142
  beq $a1, $t1, print_zero

Noémie Fong's avatar
Noémie Fong committed
143
# We use this block to compute the display of a digit - seconds, minutes, hours
144
digits:
145
146
147
148
149
150
151
152
153
154
# We set the return value
  add $ra, $zero, $s7
# We test if an update is necessary
  beq $t0, $zero, break
  add $ra, $zero, $s6
# We test whether we reached 24 hours
# Remember that $t2 = 2 when we deal with hours.
  bne $t2, $zero, print_zero_digit
  xor $t0, $t0, $t0
  addi $a2, $a2, 1
Noémie Fong's avatar
Noémie Fong committed
155
  addi $t1, $zero, 1
156
157
# We test the value of $a2
  beq $a2, $t1, print_one
Noémie Fong's avatar
Noémie Fong committed
158
  addi $t1, $t1, 1
159
  beq $a2, $t1, print_two
Noémie Fong's avatar
Noémie Fong committed
160
  addi $t1, $t1, 1
161
  beq $a2, $t1, print_three
Noémie Fong's avatar
Noémie Fong committed
162
  addi $t1, $t1, 1
163
  beq $a2, $t1, print_four
Noémie Fong's avatar
Noémie Fong committed
164
  addi $t1, $t1, 1
165
  beq $a2, $t1, print_five
Noémie Fong's avatar
Noémie Fong committed
166
  addi $t1, $t1, 1
167
  beq $a2, $t1, print_zero_digit
168

169
170
# The following blocks compute a possible update of the month.
# This is where we compute whether it is a leap year or not.
171
172
173
day_29:
# We are sent here from the tests on the day
# $a1 is the day, $a2 is the month
Martin Pépin's avatar
Martin Pépin committed
174
  addi $t4, $zero, 2
175
176
177
178
179
180
181
182
183
184
  bne $a2, $t4, update_days
# We test whether the year is a leap year
# First, if the modulo is 4
  andi $t4, $s3, 3
  beq $t4, $zero, year_100
  addi $t0, $zero, 1
  j update_days

# Then, if it is a multiple of four, whether our leap year counter is 25
year_100:
185
186
# Update the counter first.
  addi $s4, $s4, 1
Martin Pépin's avatar
Martin Pépin committed
187
  addi $t4, $zero, 25
188
  beq $s4, $t4, year_400
189

190
191
# If we didn't jump, it's a leap year.
leap_year:
192
193
194
# The day should be 1
  addi $a1, $zero, 1
  addi $t0, $zero, 1
195
196
197
  j update_days

year_400:
198
199
# We need to reset our counter
  xor $s4, $s4, $s4
200
201
# We test whether the year is a multiple of 400
# If it is, it's a leap year
202
  andi $t4, $a1, 15
203
  beq $t4, $zero, leap_year
204
205
  addi $a1, $a1, 1
  j update_days
206

207
208
209
210
211
212
213
214
# This is to test whether we are a 29/02
day_30:
  addi $t4, $zero, 2
  bne $a2, $t4, update_days
# If this is indeed a 29/02
  addi $a1, $zero, 1
  addi $t0, $zero, 1
  j update_days
215

216
217
218
219
220
day_31:
# We use the discrimination from $s0 to decide if a month has 30 or 31 days
  srlv $t4, $s0, $a2
  andi $t4, $t4, 1
# $t4 = 0 if the month has 30 days, $t4 = 1 otherwise
Noémie Fong's avatar
Noémie Fong committed
221
  bne $t4, $zero, update_days
222
223
224
225
226
227
228
# j day_32

# Here, we always need to update the month.
day_32:
  addi $a1, $zero, 1
  addi $t0, $zero, 1
  j update_days
229

230
231
232
233
# For when we need to roll around to a new year
month_13:
  addi $a2, $zero, 1
  addi $t0, $zero, 1
Noémie Fong's avatar
Noémie Fong committed
234
  j update_months
235
236
237


# Beginning of each loop
238
seconds:
Noémie Fong's avatar
Noémie Fong committed
239
  xor $t7, $t7, $t7
240
241
242
  xor $a1, $a1, $a1
  xor $a2, $a2, $a2
# We fetch the stored values of the seconds
243
244
  add $a1, $zero, $k0
  add $a2, $zero, $k1
Noémie Fong's avatar
Noémie Fong committed
245
  srl $a2, $a2, 4
246
247
248
# We empty the print argument
  xor $a0, $a0, $a0
  xor $t0, $t0, $t0
Noémie Fong's avatar
Noémie Fong committed
249
250
# $t2 is the flag for when we reached 24h.
  xor $t2, $t2, $t2
251
252
253
254
255
256
  la $s7, update_sec_units
  la $s6, update_sec_digits
  j unit

update_sec_digits:
# Update the digits
257
  add $k1, $zero, $a2
258
259
260

update_sec_units:
# Update the units
261
  add $k0, $zero, $a1
262
  beq $t0, $zero, clock
263
264

minutes:
265
266
267
268
269
  xor $a0, $a0, $a0
  xor $a1, $a1, $a1
  xor $a2, $a2, $a2
  xor $t0, $t0, $t0
# We fetch the stored values of the minutes
270
271
  add $a1, $zero, $t8
  add $a2, $zero, $t9
272
273
274
275
276
277
  la $s7, update_min_units
  la $s6, update_min_digits
  j unit

update_min_digits:
# Update the digits
278
  add $t9, $zero, $a2
279
280
281

update_min_units:
# Update the units
282
  add $t8, $zero, $a1
283
284
  beq $t0, $zero, clock
#  j hours
285
286

hours:
287
288
289
290
  xor $a0, $a0, $a0
  xor $a1, $a1, $a1
  xor $a2, $a2, $a2
  xor $t0, $t0, $t0
Noémie Fong's avatar
Noémie Fong committed
291
292
# We are treating the hours, so $t7 = 2
  addi $t7, $zero, 2
293
# We fetch the stored values of the hours
294
295
  add $a1, $zero, $fp
  add $a2, $zero, $sp
296
297
298
299
300
301
302
# We set the return adresses
  la $s7, update_hours_units
  la $s6, update_hours_digits
  j unit

update_hours_digits:
# Update the digits
303
  add $sp, $zero, $a2
304
305
306

update_hours_units:
# Update the units
307
  add $fp, $zero, $a1
308
309
  beq $t0, $zero, clock
#  j days
310
311

days:
312
313
314
315
316
  xor $a0, $a0, $a0
  xor $a1, $a1, $a1
  xor $a2, $a2, $a2
  xor $t0, $t0, $t0
# We fetch the current day and month
317
318
  add $a1, $zero, $s1
  add $a2, $zero, $s2
Noémie Fong's avatar
Noémie Fong committed
319
320
# We update the day
  addi $a1, $a1, 1
321
322
323
324
325
326
327
328
329
330
331
332
# We have some tests to do according to the next day
  addi $t3, $zero, 29
  beq $a1, $t3, day_29
  addi $t3, $t3, 1
  beq $a1, $t3, day_30
  addi $t3, $t3, 1
  beq $a1, $t3, day_31
  addi $t3, $t3, 1
  beq $a1, $t3, day_32
# If we haven't jumped, we must stay in the same month

update_days:
333
334
335
336
337
338
339
# We print the new day
  add $a0, $zero, $a1
  li $v0, 1
  syscall
  la $a0, line
  li $v0, 4
  syscall
340
  add $s1, $zero, $a1
341
342
  beq $t0, $zero, clock
# j months
Noémie Fong's avatar
Noémie Fong committed
343

344
months:
345
346
347
348
349
350
351
352
  xor $t0, $t0, $t0
# At this point, $a2 already contains the month
  addi $a2, $a2, 1
  addi $t4, $zero, 13
  beq $a2, $t4, month_13
# j update_months

update_months:
353
354
355
356
357
358
359
# We print the new month
  add $a0, $zero, $a2
  li $v0, 1
  syscall
  la $a0, line
  li $v0, 4
  syscall
360
361
362
363
364
365
# Screen $s3 to erase the month
  andi $s4, $s4, 31
  sll $a2, $a2, 5
  or $s4, $s4, $a2
  beq $t0, $zero, clock
# j years
366
367

years:
368
369
# We only have to add 1 to the current year.
  addi $s3, $s3, 1
370
371
372
373
374
375
376
377
# We print the new year
  add $a0, $zero, $s3
  li $v0, 1
  syscall
  la $a0, line
  li $v0, 4
  syscall
# Time to restart the loop
378
  j clock
379
380

.data
381
382
383
384
385
386
387
388
389
390
391
  zero: .asciiz "1011111\n"
  one: .asciiz "0000110\n"
  two: .asciiz "0111011\n"
  three: .asciiz "0101111\n"
  four: .asciiz "1100110\n"
  five: .asciiz "1101101\n"
  six: .asciiz "1111101\n"
  seven: .asciiz "0000111\n"
  eight: .asciiz "1111111\n"
  nine: .asciiz "1101111\n"
  line: .asciiz "\n"
Noémie Fong's avatar
Noémie Fong committed
392
  end: .asciiz "EOF\n"