Repository navigation
Expand file tree
/
Copy pathprogram.s
More file actions
executable file
·98 lines (78 loc) · 2.04 KB
/
Copy pathprogram.s
File metadata and controls
executable file
·98 lines (78 loc) · 2.04 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
.section ".text.init"
# Memory-mapped I/O addresses
.equ BUTTON_BASE, 0x70000000
.equ LED_BASE, 0x50000000
.equ GAME_STATE, 0x90000000
.equ COUNTDOWN, 0x90000004
.equ SP_BASE, 0x9FFFFFC0
# Countdown length per round (cycles). Keep in sync with kCountdownTotal in
# src/play.cpp, which draws the on-screen countdown bar.
.equ COUNTDOWN_CYCLES, 5000
# Register offsets for button controller
.equ BTN_SRC_OFF, 4
.equ BTN_PTM_OFF, 8
.equ BTN_STM_OFF, 12
.globl _start
_start:
li sp, SP_BASE
# Set up interrupt vector
lui t0, %hi(interrupt_handler)
addi t0, t0, %lo(interrupt_handler)
csrw mtvec, t0
# Every push button / switch triggers on a rising edge
li t0, BUTTON_BASE
li t1, 0x55555
sw t1, BTN_PTM_OFF(t0)
li t1, 0x5555
sw t1, BTN_STM_OFF(t0)
# Enable machine-mode external interrupts
li t0, 0x800
csrs mie, t0
li t0, 0x8
csrs mstatus, t0
li s1, LED_BASE
li s0, COUNTDOWN
# One round of the reaction game: press a button before the countdown ends.
round:
# Start in the LOSE state
li t0, GAME_STATE
sw zero, 0(t0)
# Countdown - the interrupt handler flips the state to 1 (WIN)
li t0, COUNTDOWN_CYCLES
wait_loop:
addi t0, t0, -1
sw t0, 0(s0) # publish the remaining count for the display
bnez t0, wait_loop
# Load and check the game result
li t0, GAME_STATE
lw t1, 0(t0)
beqz t1, lose
win:
li t1, 0x000007FF # clear all LED channels (pattern 0, all channels selected)
sw t1, 0(s1)
li t1, 0xFFFF02FF # Set green LEDs on for all
sw t1, 0(s1)
j round
lose:
li t1, 0x000007FF # clear all LED channels
sw t1, 0(s1)
li t1, 0xFFFF01FF # Set red LEDs on for all
sw t1, 0(s1)
j round
interrupt_handler:
addi sp, sp, -16
sw ra, 12(sp)
sw s0, 8(sp)
sw s1, 4(sp)
sw t0, 0(sp)
li t0, BUTTON_BASE
sw x0, BTN_SRC_OFF(t0)
li t3, GAME_STATE
li t4, 1
sw t4, 0(t3)
lw ra, 12(sp)
lw s0, 8(sp)
lw s1, 4(sp)
lw t0, 0(sp)
addi sp, sp, 16
mret