-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscore.asm
executable file
·240 lines (202 loc) · 4.03 KB
/
score.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
; score.asm
;
; Manage current score, line clears and level.
.equ PTS_TETRIS = 50
.equ PTS_TRIPLE = 30
.equ PTS_DOUBLE = 20
.equ PTS_SINGLE = 10
.equ PTS_HARD_DROP = 2 ; For each line in a hard drop
.equ PTS_SOFT_DROP = 1 ; For one soft drop
.equ LINES_TETRIS = 8
.equ LINES_TRIPLE = 5
.equ LINES_DOUBLE = 3
.equ LINES_SINGLE = 1
.equ LINES_PER_LEVEL = 5
.eseg
highscore:
.db 0,0,0,0 ; 4 bytes, low bytes to the left
maxlevel:
.db 0 ; 1 byte
.dseg
level:
.byte 1 ; Level 1 through 15 (Stored as 0x01 thru 0x0f)
score:
.byte 4 ; Goes up to 4'294'967'296 (left bit has lower exponent?)
lines:
.byte 1 ; Lines left until next level (0 through 75)
.cseg
.macro SCORE_ADD ; pts
ldi b0, low(@0)
ldi b1,high(@0)
rcall score_adder
.endmacro
.macro LINE_ADD ; lines
ldi a0,@0
rcall line_adder
.endmacro
; Initialize score variable
; mod w
; out level,score,lines
score_init:
ldi w,0x01 ; Default level is 1
sts level,w
ldi w,0x00
sts score, w
sts score+1,w
sts score+2,w
sts score+3,w
sts lines,w
ret
; Add any number (0 thru 65535) of points
; in b0,b1,score
; mod a0,a1,a2,a3
; out score
score_adder:
lds a0,score ; LDS4 a3,a2,a1,a0,score
lds a1,score+1
lds a2,score+2
lds a3,score+3
add a0,b0 ; ADDI4 a3,a2,a1,a0,w
adc a1,b1
brcc PC+4
inc a2
brne PC+2
inc a3
sts score, a0 ; STS4 score,a3,a2,a1,a0
sts score+1,a1
sts score+2,a2
sts score+3,a3
MOV4 b3,b2,b1,b0,a3,a2,a1,a0
rcall highscore_load ; b = score, a = highscore
CP4 a3,a2,a1,a0,b3,b2,b1,b0 ; Update highscores
brge _score_adder_0
MOV4 a3,a2,a1,a0,b3,b2,b1,b0
rcall highscore_store
lds a0,level
LDIX maxlevel
rcall eeprom_store
_score_adder_0:
ret
; Add any number (0 thru 255) of lines & handle the lvel-logic
; in a0
; mod a0,a1,w
line_adder:
lds a1,lines; a1 := lines
add a1,a0
sts lines,a1
lds w,level ; Detect whether we're ok for level up
tst w
breq PC+4 ; (loop end)
dec w
subi a1,LINES_PER_LEVEL
rjmp PC-4
tst a1
brpl PC+2 ; Branch if enough lines for lvl up
ret
sts lines,a1 ; Store lines after level up
rcall level_up
ret
; Increment level & accelerate game
; in level,OCR0
; mod w,a0,a1
; out level,OCR0
level_up:
lds w,level ; Level up
inc w
sts level,w
in a0,OCR0 ; Accelerate
ldi a1,16
sub a1,w ; a1 := 16 - level
sub a0,a1
out OCR0,a0
ret
; Score a tetris
; mod a0,a1,a2,a3
score_tetris:
SCORE_ADD PTS_TETRIS
LINE_ADD LINES_TETRIS
rcall score_display
ret
; Score a triple
; mod a0,a1,a2,a3
score_triple:
SCORE_ADD PTS_TRIPLE
LINE_ADD LINES_TRIPLE
rcall score_display
ret
; Score a double
; mod a0,a1,a2,a3
score_double:
SCORE_ADD PTS_DOUBLE
LINE_ADD LINES_DOUBLE
rcall score_display
ret
; Score a single
; mod a0,a1,a2,a3
score_single:
SCORE_ADD PTS_SINGLE
LINE_ADD LINES_SINGLE
rcall score_display
ret
; Score soft-drop line down
; mod a0,a1,a2,a3
score_soft_drop:
SCORE_ADD PTS_SOFT_DROP
rcall score_display
ret
; Score hard-drop line down
; mod a0,a1,a2,a3
score_hard_drop:
SCORE_ADD PTS_HARD_DROP
rcall score_display
ret
; Display score on LCD screen
; mod a0,a1,a2,a3,X
score_display:
LDIX score ; Line 1: Score
ld a0,X+
ld a1,X+
ld a2,X+
ld a3,X+
rcall LCD_home
PRINTF LCD
.db CR,FDEC4,a," pts ",LF,0
lds a0,level ; Line 2: Level & lines
lds b0,lines
PRINTF LCD
.db "L",FDEC,a," (",FDEC,b," lines) ",0,0
ret
; Load highscore from EEPROM
; in highscore
; mod X
; out a0,a1,a2,a3
highscore_load:
LDIX highscore+3
rcall eeprom_load
dec xl
mov a3,a0
rcall eeprom_load
dec xl
mov a2,a0
rcall eeprom_load
dec xl
mov a1,a0
rcall eeprom_load ; highscore is inside |a0 a1 a2 a3| now
ret
; Store number into highscore inside EEPROM
; in a0,a1,a2,a3
; mod X
; out highscore
highscore_store:
LDIX highscore
rcall eeprom_store
inc xl
mov a0,a1
rcall eeprom_store
inc xl
mov a0,a2
rcall eeprom_store
inc xl
mov a0,a3
rcall eeprom_store
ret