forked from cepa/snake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
snake.asm
1558 lines (1424 loc) · 37.4 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
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;====================================================;
;= SNAKE =;
;= =;
;= By Lukasz (Cepa) Cepowski 2004 =;
;= [email protected] =;
;= Visit cepa.io =;
;= =;
;====================================================;
; 2004-07-13
; NASM
; nasm -o snake.com -fbin snake.asm
%define VGA_MEM 0A000H ; video memory bank
%define SCR_MEM 09000H ; last 64kB segment
%define FONT_SEG 0F000H ; ROM-Font segment
%define FONT_OFF 0FA6EH ; ROM-Font offset
%define TRANSPARENT_COLOR 0
%define KEY_ESC 1
%define KEY_UP 72
%define KEY_DOWN 80
%define KEY_LEFT 75
%define KEY_RIGHT 77
%define KEY_A 30
%define KEY_P 25
CPU 186
BITS 16
ORG 100H
JMP main
; keyboard routines
keyboard_int:
STI
PUSH AX
IN AL,60H ; get key from keyboard port
MOV [CS:lastkey],AL
POP AX
PUSH AX
PUSH CX
MOV AX,0
MOV AL,[CS:lastkey]
CMP AL,128 ; check keyboard data (pressed or not)
JNAE check_keys_1
SUB AL,128
MOV CL,0
JMP check_keys_2
check_keys_1:
MOV CL,1
check_keys_2:
MOV BX,key
ADD BX,AX
MOV [CS:BX],CL
POP CX
POP AX
PUSH AX
MOV AL,20H ; send end of irq
OUT 20H,AL
POP AX
CLI
IRET
install_keyboard:
MOV AX,3509H ; get old keyboard int proc
INT 21H
MOV [CS:old_keyboard_int],BX
MOV [CS:old_keyboard_int + 2],ES
MOV AX,2509H ; set new keyboard int proc
MOV DX,keyboard_int
PUSH DS
PUSH CS
POP DS
INT 21H
POP DS
RET
remove_keyboard:
MOV AX,2509H ; restore old keyboard proc
LDS DX,[CS:old_keyboard_int]
INT 21H
RET
wait_for_any_key:
MOV BYTE [lastkey],0
MOV DL,[lastkey]
wait_for_any_key_1:
CMP DL,[lastkey]
JE wait_for_any_key
RET
;-------
; timer routines
timer_int:
STI
MOV BYTE [CS:can_update],1 ; update game
INC BYTE [CS:timer_counter]
CMP BYTE [CS:timer_counter],18
JE timer_int_reset_delay
JMP timer_int_end
timer_int_reset_delay:
MOV BYTE [CS:timer_delay],0
MOV BYTE [CS:timer_counter],0
timer_int_end:
CLI
IRET
install_timer:
MOV AX,351CH ; get old timer int proc
INT 21H
MOV [CS:old_timer_int],BX
MOV [CS:old_timer_int + 2],ES
MOV AX,251CH ; set new timer int proc
MOV DX,timer_int
PUSH DS
PUSH CS
POP DS
INT 21H
POP DS
RET
remove_timer:
MOV AX,251CH ; restore old timer proc
LDS DX,[CS:old_timer_int]
INT 21H
RET
;-------
; gfx routines
init13h:
MOV AX,0013H ; set 320x200 8bit video mode
INT 10H
RET
close13h:
MOV AX,0003H ; restore text mode
INT 10H
RET
vsync: ; wait for end of screen updating
PUSH AX
PUSH DX
MOV DX,03DAH
vsync_1:
IN AL,DX
TEST AL,0
JNE vsync_1
POP DX
POP AX
RET
set_palette:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,0
MOV BX,palette ; load palette adress to BX
MOV CX,256 ; 256 colors (8bit)
set_palette_1:
PUSH AX
MOV DX,03C8H ; set first VGA DAC port
OUT DX,AL ; send color num (AL) to VGA DAC
INC DX ; set next port
MOV AL,[BX] ; send RGB and increment BX pointer
OUT DX,AL
INC BX
MOV AL,[BX]
OUT DX,AL
INC BX
MOV AL,[BX]
OUT DX,AL
INC BX
POP AX
INC AL ; increment color num
LOOP set_palette_1
POP DX
POP BX
POP CX
POP AX
RET
draw_screen: ; move data from 9000h to A000h segment
CALL vsync
PUSH DS
PUSH ES
PUSH AX
PUSH CX
PUSH DI
MOV AX,SCR_MEM
MOV DS,AX
MOV AX,VGA_MEM
MOV ES,AX
MOV CX,64000
draw_screen_1:
MOV DI,CX
DEC DI
MOV AL,[DS:DI]
MOV [ES:DI],AL
LOOP draw_screen_1
POP DI
POP CX
POP AX
POP ES
POP DS
RET
clear_screen: ; clear screen buffer, CL - color
PUSH ES
PUSH AX
PUSH DI
MOV AX,SCR_MEM
MOV ES,AX
MOV AL,CL
MOV CX,64000
clear_screen_1:
MOV DI,CX
DEC DI
MOV [ES:DI],AL
LOOP clear_screen_1
POP DI
POP AX
POP ES
RET
putpixel: ; AX - x, BX - y, CL - color
PUSH AX
PUSH BX
PUSH CX
PUSH DI
PUSH ES
PUSH AX
MOV AX,BX
MOV BX,320
MUL BX
POP BX
ADD AX,BX
MOV DI,AX
MOV AX,SCR_MEM
MOV ES,AX
MOV [ES:DI],CL
POP ES
POP DI
POP CX
POP BX
POP AX
RET
getpixel: ; AX - x, BX - y, return: CL - color
PUSH AX
PUSH BX
PUSH DI
PUSH ES
PUSH AX
MOV AX,BX
MOV BX,320
MUL BX
POP BX
ADD AX,BX
MOV DI,AX
MOV AX,SCR_MEM
MOV ES,AX
MOV CL,[ES:DI]
POP ES
POP DI
POP BX
POP AX
RET
draw_sprite: ; SX - x, SY - y, SW - width, SH - height, BX - data
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DI
MOV AX,SCR_MEM
MOV ES,AX
MOV AX,[SY]
MOV CX,[SH]
draw_sprite_y_axis:
PUSH CX
PUSH AX
MOV DX,320
MUL DX
ADD AX,[SX]
MOV DI,AX
MOV CX,[SW]
draw_sprite_x_axis:
MOV AL,[BX]
MOV [ES:DI],AL
INC DI
INC BX
LOOP draw_sprite_x_axis
POP AX
INC AX
POP CX
LOOP draw_sprite_y_axis
POP DI
POP ES
POP DX
POP CX
POP BX
POP AX
RET
draw_transparent_sprite: ; SX - x, SY - y, SW - width, SH - height, BX - data
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DI
MOV AX,SCR_MEM
MOV ES,AX
MOV AX,[SY]
MOV CX,[SH]
draw_transparent_sprite_y_axis:
PUSH CX
PUSH AX
MOV DX,320
MUL DX
ADD AX,[SX]
MOV DI,AX
MOV CX,[SW]
draw_transparent_sprite_x_axis:
MOV AL,[BX]
CMP AL,TRANSPARENT_COLOR
JE draw_transparent_sprite_x_next
MOV [ES:DI],AL
draw_transparent_sprite_x_next
INC DI
INC BX
LOOP draw_transparent_sprite_x_axis
POP AX
INC AX
POP CX
LOOP draw_transparent_sprite_y_axis
POP DI
POP ES
POP DX
POP CX
POP BX
POP AX
RET
hline: ; PX1 - x1, PY1 - y, PX2 - x2, PCL - color
PUSH ES
PUSH DI
PUSH AX
PUSH BX
PUSH CX
MOV AX,SCR_MEM
MOV ES,AX
MOV AX,[PY1]
MOV BX,320
MUL BX
ADD AX,[PX1]
MOV DI,AX
MOV AL,[PCL]
MOV CX,[PX2]
SUB CX,[PX1]
hline_1:
MOV BYTE [ES:DI],AL
INC DI
LOOP hline_1
POP CX
POP BX
POP AX
POP DI
POP ES
RET
vline: ; PX1 - x, PY1 - y1, PY2 - y2, PCL - color
PUSH ES
PUSH DI
PUSH AX
PUSH BX
PUSH CX
MOV AX,SCR_MEM
MOV ES,AX
MOV AX,[PY1]
MOV BX,320
MUL BX
ADD AX,[PX1]
MOV DI,AX
MOV AL,[PCL]
MOV CX,[PY2]
SUB CX,[PY1]
vline_1:
MOV [ES:DI],AL
ADD DI,320
LOOP vline_1
POP CX
POP BX
POP AX
POP DI
POP ES
RET
rect: ; PX1 - x1, PY1 - y1, PX2 - x2, PY2 - y2, PCL - color
PUSH AX
PUSH BX
PUSH CX
CALL hline
CALL vline
MOV AX,[PY1]
MOV BX,[PY2]
MOV [PY1],BX
CALL hline
MOV [PY1],AX
MOV AX,[PX1]
MOV BX,[PX2]
MOV [PX1],BX
CALL vline
MOV [PX1],AX
MOV AX,[PX2]
MOV BX,[PY2]
MOV CL,[PCL]
CALL putpixel
POP CX
POP BX
POP AX
RET
rectfill:
PUSH AX
PUSH CX
MOV AX,[PY1]
MOV CX,[PY2]
SUB CX,[PY1]
rectfill_1:
CALL hline
INC WORD [PY1]
LOOP rectfill_1
MOV [PY1],AX
CALL rect
POP CX
POP AX
RET
draw_char_mask: ; AX - x, BX - y, CL - color, CH - char mask
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV DX,CX
MOV CX,8
draw_char_mask_1:
PUSH CX
SHL DH,1
JNC draw_char_mask_2
PUSH DX
MOV CL,DL
CALL putpixel
POP DX
draw_char_mask_2:
POP CX
INC AX
LOOP draw_char_mask_1
POP DX
POP CX
POP BX
POP AX
RET
draw_char: ; AX - x, BX - y, CL - color, CH - char
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DI
PUSH AX
MOV AX,FONT_SEG
MOV ES,AX
MOV AX,FONT_OFF
MOV DI,AX
MOV AX,0
MOV AL,CH
SHL AX,3
ADD DI,AX
POP AX
MOV DX,CX
MOV CX,8
draw_char_1:
PUSH CX
MOV CX,DX
MOV CH,[ES:DI]
CALL draw_char_mask
INC DI
INC BX
POP CX
LOOP draw_char_1
POP DI
POP ES
POP DX
POP CX
POP BX
POP AX
RET
draw_integer: ; AX - x, BX - y, CL - color, DX - integer
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV DI,10000
MOV [draw_integer_cl],CL
MOV CX,5
draw_integer_1:
PUSH CX
PUSH AX
PUSH BX
PUSH DX
MOV AX,DX
XOR DX,DX
MOV BX,DI
DIV BX
MOV CH,AL
MUL BX
POP DX
SUB DX,AX
POP BX
POP AX
ADD CH,'0'
MOV CL,[draw_integer_cl]
CALL draw_char
ADD AX,8
PUSH AX
PUSH BX
PUSH DX
MOV AX,DI
MOV BX,10
XOR DX,DX
DIV BX
MOV DI,AX
POP DX
POP BX
POP AX
POP CX
LOOP draw_integer_1
POP DI
POP DX
POP CX
POP BX
POP AX
RET
draw_integer_cl DB 0 ; color (temp)
draw_text: ; AX - x, BX - y, CL - color, DX - data
PUSH AX
PUSH BX
PUSH CX
PUSH DX
XCHG BX,DX
draw_text_1:
MOV CH,[BX]
INC BX
XCHG BX,DX
CALL draw_char
ADD AX,8
XCHG BX,DX
CMP BYTE [BX],0
JNE draw_text_1
POP DX
POP CX
POP BX
POP AX
RET
;-------
; program code
random_init:
PUSH AX
PUSH CX
PUSH DX
MOV AH,2CH
INT 21H
MOV [random_seed],DX
POP DX
POP CX
POP AX
RET
random_gen: ; return: CL - random byte
MOV CX,[random_seed]
IMUL CX,13A7H
INC CX
MOV [random_seed],CX
MOV CL,CH
MOV CH,0
RET
random: ; AL - max random number
CALL random_gen
CMP CL,AL
JAE random
RET
random_seed DW 0 ; seed
delay: ; AX - hund. seconds (1/100 s)
MOV BYTE [timer_delay],1
delay_1:
CMP BYTE [timer_delay],0
JNE delay_1
RET
sound_on:
PUSH AX
MOV AL,0B6H
OUT 43H,AL
MOV AX,11930
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
OR AL,3
OUT 61H,AL
POP AX
RET
sound_off:
PUSH AX
IN AL,61H
AND AL,252
OUT 61H,AL
POP AX
RET
move_snake:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
CMP BYTE [snake_vector],0
JE move_snake_end
MOV CX,[snake_len]
DEC CX
move_snake_1:
PUSH CX
DEC CX
MOV BX,snake
MOV AX,CX
MOV CX,4
MUL CX
ADD BX,AX
MOV AX,[BX]
MOV CX,[BX + 2]
MOV [BX + 4],AX
MOV [BX + 6],CX
POP CX
LOOP move_snake_1
CMP BYTE [snake_vector],1
JE move_snake_up
CMP BYTE [snake_vector],2
JE move_snake_down
CMP BYTE [snake_vector],3
JE move_snake_left
CMP BYTE [snake_vector],4
JE move_snake_right
move_snake_up:
SUB WORD [snake + 2],5
JMP move_snake_vector_end
move_snake_down:
ADD WORD [snake + 2],5
JMP move_snake_vector_end
move_snake_left:
SUB WORD [snake],5
JMP move_snake_vector_end
move_snake_right:
ADD WORD [snake],5
JMP move_snake_vector_end
move_snake_vector_end:
move_snake_end:
POP DX
POP CX
POP BX
POP AX
RET
set_snakes_vector:
PUSH AX
CMP AL,1
JE set_snakes_vector_up
CMP AL,2
JE set_snakes_vector_down
CMP AL,3
JE set_snakes_vector_left
CMP AL,4
JE set_snakes_vector_right
JMP set_snakes_vector_end
set_snakes_vector_up:
CMP BYTE [snake_vector],2 ; if not down
JE set_snakes_vector_up_1
MOV BYTE [snake_vector],1 ; set up
set_snakes_vector_up_1:
JMP set_snakes_vector_end
set_snakes_vector_down:
CMP BYTE [snake_vector],1 ; if not up
JE set_snakes_vector_down_1
MOV BYTE [snake_vector],2 ; set down
set_snakes_vector_down_1:
JMP set_snakes_vector_end
set_snakes_vector_left:
CMP BYTE [snake_vector],4 ; if not right
JE set_snakes_vector_left_1
CMP BYTE [snake_vector],0 ; if not 'no move'
JE set_snakes_vector_left_1
MOV BYTE [snake_vector],3 ; set left
set_snakes_vector_left_1:
JMP set_snakes_vector_end
set_snakes_vector_right:
CMP BYTE [snake_vector],3 ; if not left
JE set_snakes_vector_right_1
MOV BYTE [snake_vector],4 ; set right
set_snakes_vector_right_1:
JMP set_snakes_vector_end
set_snakes_vector_end:
POP AX
RET
reset_snake:
MOV WORD [snake + 14],60
MOV WORD [snake + 12],25
MOV WORD [snake + 10],60
MOV WORD [snake + 8],30
MOV WORD [snake + 6],60
MOV WORD [snake + 4],35
MOV WORD [snake + 2],60
MOV WORD [snake],40
MOV WORD [snake_len],4
MOV BYTE [snake_vector],0
RET
reset_food:
PUSH AX
PUSH BX
PUSH CX
; random food x
MOV AL,58 ; max area width / 5
CALL random
MOV AH,0
MOV AL,CL
MOV BX,5
MUL BX
ADD AX,5
MOV [snakes_food_x],AX
; random food y
MOV AL,35 ; max area height / 5
CALL random
MOV AH,0
MOV AL,CL
MOV BX,5
MUL BX
ADD AX,20
MOV [snakes_food_y],AX
POP CX
POP BX
POP AX
RET
increase_snake: ; snake++ :), new head = food position
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX,[snake_len]
increase_snake_1:
PUSH CX
DEC CX
MOV BX,snake
MOV AX,CX
MOV CX,4
MUL CX
ADD BX,AX
MOV AX,[BX]
MOV CX,[BX + 2]
MOV [BX + 4],AX
MOV [BX + 6],CX
POP CX
LOOP increase_snake_1
MOV AX,[snakes_food_x]
MOV [snake],AX
MOV AX,[snakes_food_y]
MOV [snake + 2],AX
INC WORD [snake_len]
MOV AX,[snake_len]
CMP AX,[snake_max_len] ; if snake_len == snake_max_len then print winner msg and quit
JE increase_snake_max_len
JMP increase_snake_end
increase_snake_max_len:
CALL winner
increase_snake_end:
POP DX
POP CX
POP BX
POP AX
RET
detect_collisions: ; detect collisions beetwen objects
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; detect head and food collision
MOV AX,[snakes_food_x]
CMP AX,[snake] ; compare food x with head x
JNE detect_collisions_1
MOV AX,[snakes_food_y]
CMP AX,[snake + 2] ; compare food y with head y
JNE detect_collisions_1
; add points and increase snake
ADD WORD [score],10 ; add 10 points :)
CALL increase_snake
CALL reset_food
detect_collisions_1:
; detect collision with border and decrase lives
CMP WORD [snake],0 ; coll. with left border
JE detect_collisions_dead
CMP WORD [snake],320 - 5 ; coll. with right border
JE detect_collisions_dead
CMP WORD [snake + 2],15 ; coll. with top border
JE detect_collisions_dead
CMP WORD [snake + 2],200 - 5 ; coll. with bottom border
JE detect_collisions_dead
; detect head collision with body
MOV BX,snake
ADD BX,8 ; jump to next x&y
MOV AX,[snake]
MOV DX,[snake + 2]
MOV CX,[snake_len]
DEC CX
detect_collisions_head_with_body:
CMP AX,[BX]
JNE detect_collisions_head_with_body_next
CMP DX,[BX + 2]
JE detect_collisions_dead
detect_collisions_head_with_body_next:
ADD BX,4
LOOP detect_collisions_head_with_body
; if everything is ok the jump to the end
JMP detect_collisions_end
detect_collisions_dead:
CALL reset_snake
CALL reset_food
DEC BYTE [live_counter]
MOV AX,1000
CALL draw_screen
CALL sound_on
CALL delay
CALL sound_off
detect_collisions_end:
POP DX
POP CX
POP BX
POP AX
RET
main:
CALL init13h
CALL install_keyboard
CALL install_timer
CALL set_palette
CALL random_init
; setup snake
CALL reset_snake
CALL reset_food
game_loop:
; synchronize game
CMP BYTE [can_update],1
JNE game_loop
MOV BYTE [can_update],0
; clear screen buffer
MOV CL,0
CALL clear_screen
; draw frame
MOV BX,sprite_frame_box
MOV WORD [SW],5
MOV WORD [SH],5
; draw top frame
MOV WORD [SX],0
MOV WORD [SY],0
MOV CX,320 / 5
draw_frame_top:
CALL draw_sprite
ADD WORD [SX],5
LOOP draw_frame_top
; draw bottom frame
MOV WORD [SX],0
MOV WORD [SY],200 - 5
MOV CX,320 / 5
draw_frame_bottom:
CALL draw_sprite
ADD WORD [SX],5
LOOP draw_frame_bottom
; draw left frame
MOV WORD [SX],0
MOV WORD [SY],0
MOV CX,200 / 5
draw_frame_left:
CALL draw_sprite
ADD WORD [SY],5
LOOP draw_frame_left
; draw_frame_right
MOV WORD [SX],320 - 5
MOV WORD [SY],0
MOV CX,200 / 5
draw_frame_right:
CALL draw_sprite
ADD WORD [SY],5
LOOP draw_frame_right
; draw top bar
MOV WORD [PX1],5
MOV WORD [PY1],5
MOV WORD [PX2],320 - 5 - 1
MOV WORD [PY2],5 + 13 + 1
MOV BYTE [PCL],43
CALL rectfill
MOV BYTE [PCL],53
CALL rect
; draw logo
MOV BX,sprite_logo
MOV WORD [SX],320 / 2 - 54 / 2
MOV WORD [SY],7
MOV WORD [SW],54
MOV WORD [SH],11
CALL draw_transparent_sprite
; draw live counter
MOV BX,sprite_snake_live_0
MOV WORD [SW],13
MOV WORD [SH],11
MOV WORD [SY],7
MOV WORD [SX],320 - 5 - 18
CALL draw_transparent_sprite
MOV WORD [SX],320 - 5 - 18 - 18
CALL draw_transparent_sprite
MOV WORD [SX],320 - 5 - 18 - 18 - 18
CALL draw_transparent_sprite
MOV BX,sprite_snake_live_1
CMP BYTE [live_counter],0 ; if game over
JE counter_game_over