-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake.asm
426 lines (321 loc) · 7.76 KB
/
snake.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
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
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
initializeSnake:
;meant to print the initial snake at the beginning of the game or if life is lost.
pusha
push es
push ds
pop es
mov di, snake ;es:di == start of snake.
mov ax, 0
mov cx, 240
rep stosw
mov word[size], 20
mov cx, 20
mov bx, snake
mov ax, 560
mov si, 2
cmp word[level], 2
jne notInitializeLevel2
push word 0
push word 20
push word 41
call calLocation
pop ax ;21st row, 42nd column.
mov si, 160
notInitializeLevel2:
whileInitialize:
mov [bx], ax
add bx, 2
sub ax, si
loop whileInitialize
mov word[direction], 0
pop es
popa
ret
snakeHeadCell: dw 0x3c02
snakeBodyCell: dw 0x3c04
makeSnake:
pusha
mov cx, [size]
mov bx, snake ;head
push word 0xb800
pop es
whileMakeSnake
mov di, [bx]
mov ax, [snakeBodyCell]
mov word[es:di], ax
add bx, 2
loop whileMakeSnake
mov bx, [snake]
mov ax, [snakeHeadCell]
mov word[es:bx], ax
popa
ret
moveSnake:
pusha
push es
push ds
pop es
mov di, snake
mov bx, [size]
dec bx
add bx, bx
add di, bx ;es:di
mov si, di
sub si, 2 ;ds:si
mov cx, [size]
dec cx
std
rep movsw
cmp word[direction], 0 ;for right.
jne checkDownDirection
add word[snake], 2
jmp directionChecked
checkDownDirection:
cmp word[direction], 1 ;for down
jne checkLeftDirection
add word[snake], 160
jmp directionChecked
checkLeftDirection:
cmp word[direction], 2 ;for left
jne checkUpDirection
sub word[snake], 2
jmp directionChecked
checkUpDirection:
sub word[snake], 160
directionChecked:
pop es
popa
ret
collisionCheckItself:
;takes no parameter and makes a red spot at the spot of collision esle does nothing.
pusha
push es
mov ax, [snake] ;head in ax.
mov cx, [size]
dec cx
mov bx, snake
add bx, 2 ;starts checking after the head.
mov dx, -1 ;collision place.
whileCheckingCollision:
mov si, [bx]
cmp ax, si
jne notCollided
mov dx, si
notCollided:
add bx, 2
loop whileCheckingCollision
cmp dx, -1
je endCollisionCheck
push word 0xb800
pop es
mov si, dx
mov word[es:si], 0x0720
call updateLives
endCollisionCheck:
pop es
popa
ret
collisionCheckMaster:
push ax
call collisionCheckItself
call collisionCheckBoundary
cmp word[level], 1
jne snakeCollisionWithLevel1NotNeeded
push word 0
push word[snake] ;pushes head.
call generalCollisionWithLevel1Hurdles
pop ax
cmp ax, 1
jne snakeCollisionWithLevel1NotNeeded
call updateLives
snakeCollisionWithLevel1NotNeeded:
cmp word[level], 2
jne snakeCollisionWithLevel2NotNeeded
push word 0
push word[snake] ;head
call generalCollisionWithLevel2Hurdles
pop ax
cmp ax, 1
jne snakeCollisionWithPortalsCheck
call updateLives
snakeCollisionWithPortalsCheck:
push word 0
push word[snake]
call generalCollisionWithPortals
pop ax
cmp ax, 0
je snakeCollisionWithLevel2NotNeeded
push ax
call handlePortals
snakeCollisionWithLevel2NotNeeded:
pop ax
ret
elongateLeft:
;elongates the snake on left.
pusha
mov bx, snake
add bx, [size]
add bx, [size] ;bx now points off-the-tail.
mov ax, [bx - 2] ;tail in ax.
mov cx, 4
whileElongatingLeft:
sub ax, 2
mov [bx], ax
add bx, 2
loop whileElongatingLeft
add word[size], 4
popa
ret
elongateRight:
;elongates the snake on right
pusha
mov bx, snake
add bx, [size]
add bx, [size] ;bx now points off-the-tail.
mov ax, [bx - 2] ;tail in ax.
mov cx, 4
whileElongatingRight:
add ax, 2
mov [bx], ax
add bx, 2
loop whileElongatingRight
add word[size], 4
popa
ret
elongateUp:
;elongates the snake on right
pusha
mov bx, snake
add bx, [size]
add bx, [size] ;bx now points off-the-tail.
mov ax, [bx - 2] ;tail in ax.
mov cx, 4
whileElongatingUp:
sub ax, 160
mov [bx], ax
add bx, 2
loop whileElongatingUp
add word[size], 4
popa
ret
elongateDown:
;elongates the snake on right
pusha
mov bx, snake
add bx, [size]
add bx, [size] ;bx now points off-the-tail.
mov ax, [bx - 2] ;tail in ax.
mov cx, 4
whileElongatingDown:
add ax, 160
mov [bx], ax
add bx, 2
loop whileElongatingDown
add word[size], 4
popa
ret
elongateSnake:
pusha
cmp word[size], 240
je endElongateSnake
mov bx, snake
add bx, [size]
add bx, [size] ;bx poines off-the-end
mov ax, [bx - 2] ;tail
mov dx, [bx - 4] ;second to tail.
mov bx, ax
add bx, 2
cmp bx, dx ;if equal second to tail is at the right of tail, elongation should be on left.
jne checkRightElongation
call elongateLeft
jmp endElongateSnake
checkRightElongation:
mov bx, ax
sub bx, 2
cmp bx, dx ;if equal, second-to0tail is at the left of tail, elongation should be on right.
jne checkDownElongation
call elongateRight
jmp endElongateSnake
checkDownElongation:
mov bx, ax
sub bx, 160
cmp bx, dx ;if equal second-toital is above the tail, elongation should be downwards.
jne checkUpElongation
call elongateDown
jmp endElongateSnake
checkUpElongation:
mov bx, ax
add bx, 160
cmp bx, dx ;if equal second-to-tail is below the tail, elongation should be upwards.
jne endElongateSnake
call elongateUp
endElongateSnake:
popa
ret
handlePortals:
;takes one paramter. the address of the portal on video memory.
;it makes amends only for LL and RL portals. Collidision of snake with LE and RE is inconsequential.
push bp
mov bp, sp
pusha
mov bx, [bp + 4]
cmp bx, [portalLL]
jne handleRL
mov di, [portalRE]
sub di, 2 ;snake enters at one step to the left of RE portal.
mov [snake], di ;moves head to new positon.
mov word[direction], 2 ;for moving to left.
jmp handlePortalsEnd
handleRL:
cmp bx, [portalRL]
jne handlePortalsEnd
mov di, [portalLE]
add di, 2 ;snake enters at one step to the right of LE portal
mov [snake], di
mov word[direction], 0 ;move left.
handlePortalsEnd:
popa
mov sp, bp
pop bp
ret 2
diplayLives:
pusha
push es
push word 0xb800
pop es
mov di, 158 ;top right corner of screen.
mov cx, [lives]
std
mov ax, 0x0403 ;red hearts.
rep stosw
mov cx, 3 ;uses di from where it was left off.
sub cx, [lives]
mov ax, 0x0703 ;white hearts.
rep stosw
pop es
popa
ret
updateLives:
push ax
pushf
cmp word[lives], 0
je snakeAlreadyDed
push word [hitSound]
push word [soundDuration]
call generateGeneralSound
dec word[lives]
call resetTime
call resetSpeed
call displayTime
call clearScreen
call makeBoundary
call initializeSnake
snakeAlreadyDed:
popf
pop ax
ret
displayLength:
push word [size]
push word 120 ;somewhere in the second half of first row.
call printnum
ret