-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeys.asm
executable file
·107 lines (90 loc) · 1.95 KB
/
keys.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
; keys.asm
;
; Manage key-presses and stuff
.equ KEYS_MAX_BOUNCES= 36
.equ BTN_PAUSE = 7
.equ BTN_HOLD = 6
.equ BTN_HARD_DROP = 5
.equ BTN_SOFT_DROP = 4
.equ BTN_ROT_LEFT = 3
.equ BTN_LEFT = 2
.equ BTN_RIGHT = 1
.equ BTN_ROT_RIGHT = 0
.dseg
keys_state:
.byte 1 ; Debounced state
keys_delta:
.byte 1 ; What's changed
keys_index:
.byte 1
keys_buffer:
.byte KEYS_MAX_BOUNCES
.cseg
; Configure portD & initialize variables
; mod w
keys_init:
OUTI DDRD, 0x00 ; configure portD to input
in w,PIND
sts keys_state,w ; keys_state := PIND
ldi w,0x00
sts keys_delta,w ; keys_delta := 0x00
sts keys_index,w
LDIX keys_buffer
ldi w,KEYS_MAX_BOUNCES
mov u,w ; Loop over u
ldi w,0xff ; Initialize entire buffer to FF (active-low remember?)
tst u
breq PC+4 ; (loop end)
dec u
st X+,w
rjmp PC-4 ; (loop again)
ret
; On each game tick, process and debounce input keys
keys_process:
lds a0,keys_index ; Store current keys into buffer
ldi a1,0x00
LDIX keys_buffer
ADD2 xl,xh,a0,a1 ; X += index
in w,PIND
st X,w
lds w,keys_index ; Increment index (inside circular buffer)
INC_CYC w,0,KEYS_MAX_BOUNCES-1
sts keys_index,w
ldi a0,0xff ; AND entire buffer to get current state
LDIX keys_buffer
ldi w,0
cpi w,KEYS_MAX_BOUNCES
brge PC+5 ; (loop end)
inc w
ld a1,X+
and a0,a1
rjmp PC-5
lds a1,keys_state ; Store results and compute deltas
eor a1,a0
sts keys_delta,a1
sts keys_state,a0
ret
; Get whether a key was just pushed down
; in @key
; mod u,w
; out T
.macro KEYS_PRESS; key
lds u,keys_state
com u ; Active low to high
lds w,keys_delta
and u,w ; u = keys_state & keys_delta
bst u,@0
.endmacro
; Get whether a key is currently pressed
; mod u
.macro KEYS_PRESSED; key
lds u,keys_state
com u
bst u,@0
.endmacro
; Get whether a key is currently pressed (without debouncing)
.macro KEYS_PRESSED_RAW; key
in u,PIND
com u
bst u,@0
.endmacro