-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfrogger.s
2073 lines (2018 loc) · 55.1 KB
/
frogger.s
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
; Author: Bryan Moy
; 115200 baud rate
.data
border1: .string "|---------------------------------------------|", 0x0D, 0x0A
border2: .string "|*********************************************|", 0x0D, 0x0A
border3: .string "|***** ***** ***** ***** *****|", 0x0D, 0x0A
border4: .string "|~~~O~~~~~~Aaaaaa~~~~O~Aaaaaa~~~O~~~~Aaaaaa~~~|", 0x0D, 0x0A
border5: .string "|~~~LLLLLL~~~~~~~~~~LLLLLL~~~~LLLLLL~~~~~~~~~~|", 0x0D, 0x0A
border6: .string "|~~~TT~~~~~~~~TT~~~~TT~~~~~O~~~TT~~~~Aaaaaa~~~|", 0x0D, 0x0A
border7: .string "|~~~~~~~LLLLLL~~~~~~LLLLLL~~~~~~~~~~~~LLLLLL~~|", 0x0D, 0x0A
border8: .string "|.............................................|", 0x0D, 0x0A
border9: .string "| #### #### |", 0x0D, 0x0A
border10: .string "| C C C |", 0x0D, 0x0A
border11: .string "| |", 0x0D, 0x0A
border12: .string "| #### |", 0x0D, 0x0A
border13: .string "| |", 0x0D, 0x0A
border14: .string "| C C C |", 0x0D, 0x0A
border15: .string "|......................&......................|", 0x0D, 0x0A
border16: .string "|---------------------------------------------|", 0x0D, 0x0A
round_time: .string "time:60 ", 0x0D, 0x0A
level: .string "level:00 ", 0x0D, 0x0A
score: .string "score:00000 ", 0
.text
instructions: .string "The goal of the game is to accumulate as", 0x0D, 0x0A
instruction1: .string "many points by: moving forward(10pts),", 0x0D, 0x0A
instruction2: .string "getting a frog home(H)(50pts), each second", 0x0D, 0x0A
instruction3: .string "unused time(10pts), eating a fly(+)(100pts),", 0x0D, 0x0A
instruction4: .string "& increasing level(250pts). If you send a", 0x0D, 0x0A
instruction5: .string "frog to an already occupied Home slot, you", 0x0D, 0x0A
instruction6: .string "lose a life. Home are the empty slots at", 0x0D, 0x0A
instruction7: .string "the top of the board. To start game press", 0x0D, 0x0A
instruction8: .string "1 on keypad and make first move with frog", 0x0D, 0x0A
instruction9: .string "start the movement on the board & timer.", 0x0D, 0x0A
instruction10: .string "To un/pause game press 2 & to restart press", 0x0D, 0x0A
instruction11: .string "3 on keypad. To move the frog(&), use w for up,", 0x0D, 0x0A
instruction12: .string "a for left, s for down, & d for right. You", 0x0D, 0x0A
instruction13: .string "have 4 lives represented by the # of LEDs lit.", 0x0D, 0x0A
instruction14: .string "You lose a life if you collide with a car(C),", 0x0D, 0x0A
instruction15: .string "truck(####), fall in the river(~), jump on gator", 0x0D, 0x0A
instruction16: .string "head(A), or if you run out of time(60s per round).", 0x0D, 0x0A
instruction17: .string "To advance level, send 2 frogs home.", 0x0D, 0x0A
instruction18: .string "Game is over if you use up 4 lives.", 0x0D, 0x0A, 0
pause: .string "The game is paused, to unpause press 2 on keypad", 0x0D, 0x0A, 0
gameover: .string "GAMEOVER! To restart press 3 on the keypad", 0x0D, 0x0A, 0
reset1: .string "|---------------------------------------------|", 0x0D, 0x0A
reset2: .string "|*********************************************|", 0x0D, 0x0A
reset3: .string "|***** ***** ***** ***** *****|", 0x0D, 0x0A
reset4: .string "|~~~O~~~~~~Aaaaaa~~~~O~Aaaaaa~~~O~~~~Aaaaaa~~~|", 0x0D, 0x0A
reset5: .string "|~~~LLLLLL~~~~~~~~~~LLLLLL~~~~LLLLLL~~~~~~~~~~|", 0x0D, 0x0A
reset6: .string "|~~~TT~~~~~~~~TT~~~~TT~~~~~O~~~TT~~~~Aaaaaa~~~|", 0x0D, 0x0A
reset7: .string "|~~~~~~~LLLLLL~~~~~~LLLLLL~~~~~~~~~~~~LLLLLL~~|", 0x0D, 0x0A
reset8: .string "|.............................................|", 0x0D, 0x0A
reset9: .string "| #### #### |", 0x0D, 0x0A
reset10: .string "| C C C |", 0x0D, 0x0A
reset11: .string "| |", 0x0D, 0x0A
reset12: .string "| #### |", 0x0D, 0x0A
reset13: .string "| |", 0x0D, 0x0A
reset14: .string "| C C C |", 0x0D, 0x0A
reset15: .string "|......................&......................|", 0x0D, 0x0A
reset16: .string "|---------------------------------------------|", 0x0D, 0x0A
reset_round_time: .string "time:60 ", 0x0D, 0x0A
reset_level: .string "level:00 ", 0x0D, 0x0A
reset_score: .string "score:00000 ", 0
.global frogger
.global uart_init
.global timer_init
.global keypad_init
.global UART0Handler
.global Timer0Handler
.global PortAHandler
.global finish
.global ptr
.global menu
.global read_character
.global output_character
.global print_board
.global illuminate_RGB_LED
.global read_from_keypad
.global illuminate_LEDs
.global gameover_screen
.global go
.global pause_ptr
.global pause_screen
.global reset_ptr
.global score_ptr
score_ptr: .word score
reset_ptr: .word reset1
ptr: .word border1
go: .word gameover
pause_ptr: .word pause
menu: .word instructions
U0LSR: .equ 0x18
; in use: r4, r6, r10, r9, r8, r11, r12
; r4 = pointer to frog
; r6 = state of game
; r10 = lives
; r9 = to shift or not shift objects
; r8 = timer counter
; r11 = spawn register
; r12 = frog move left/right or no move
; r7 = previous character
; 0x200003A3 holds score
frogger:
STMFD SP!, {lr}
BL keypad_init
BL uart_init ; initialize uart
LDR r0, menu
BL print_board
;LDR r0, ptr
MOV r4, #0x02C5
MOVT r4, #0x2000 ; r4 = pointer frog
;BL print_board ; print board
MOV r6, #1 ; indicator for state of game
BL illuminate_RGB_LED ; light up RGB LED initially
; address 1st digit of timer = 20000315, 20000316
; address 1st digit Level = 20000347, 2nd 20000348
; Score: 20000378, 0379, 037A, 037B, 037C
MOV r10, #4
BL illuminate_LEDs
MOV r9, #1
MOV r8, #10
MOV r11, #1 ; counter
MOV r12, #1 ; indicator if frog is to move or not, 1 = stationary, 2 = to move right, 3 = to move left
MOV r7, #0x20
LDMFD SP!, {lr}
mov pc, lr
output_character:
STMFD SP!,{lr} ; Store register lr on stack
MOV r2, #0xC000
MOVT r2, #0x4000
STRB r1, [r2] ; Transmit byte
txFlag:
LDRB r3, [r2,#U0LSR] ; load byte of status register
MOV r5, #0x20 ; r5 = 0x00000020
AND r3, r3, r5 ; Mask bit 5 in status register to get TxFF
CMP r3, r5
BEQ txFlag
LDMFD sp!, {lr}
MOV pc, lr
print_board:
STMFD SP!, {lr}
MOV r1, #0x0C
BL output_character
MOV r1, #0x0A
BL output_character
MOV r1, #0x0D
BL output_character
printing
LDRB r1, [r0] ; load character
CMP r1, #0x00 ; compare to null
BEQ printing_end ; if null branch to end
BL output_character
ADD r0, r0, #1 ; increment address
B printing
printing_end
MOV r1, #0xA ; new line
BL output_character
MOV r1, #0xD ; enter
BL output_character
LDMFD SP!, {lr}
MOV pc, lr
score_fly: ; add 100 points if ate fly
STMFD SP!, {lr}
MOV r0, #0x037A
MOVT r0, #0x2000 ; hundreds place of score
LDRB r1, [r0] ; load digit
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, #1 ; add one (100 pts)
CMP r1, #9
BLE fly_nine ; branch if sum <= 9
SUB r1, r1, #10 ; if sum > 9, take difference from 10
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store difference in hundreds place
SUB r0, r0, #1 ; move to thousandth place
LDRB r1, [r0] ; load thousandth digit
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, #1 ; add one
CMP r1, #9
BLE fly_nine ; branch if thousand place sum <= 9
SUB r1, r1, #10 ; take difference of thousand place sum
ADD r1, r1, #48 ; convert to char
STRB r1, [r0]
SUB r0, r0, #1 ; go to 10 thousand place
LDRB r1, [r0]
ADD r1, r1, #1 ; add one for carry
STRB r1, [r0] ; update 10 thousand place
B score_fly_end
fly_nine
ADD r1, r1, #48 ; if sum <= 9 convert to char
STRB r1, [r0] ; store sum to hundreds place
B score_fly_end
score_fly_end
LDMFD SP!, {lr}
MOV pc, lr
collision_check:
STMFD SP!, {lr}
CMP r2, #0x7E ; hit water
BEQ hit_water
CMP r2, #0x43 ; hit car
BEQ hit_car
CMP r2, #0x23 ; hit truck
BEQ hit_truck
CMP r2, #0x2A ; hit *
BEQ hit_asterisk
CMP r2, #0x7C ; hit |
BEQ hit_border
CMP r2, #0x2D
BEQ hit_border_dash ; hit -
CMP r2, #0x41
BEQ hit_gator_head ; hit A
CMP r2, #0x4C
BEQ hit_log ; on a log
CMP r2, #0x2E
BEQ hit_dot ; hit "."
CMP r2, #0x20
BEQ hit_space ; on "space"
CMP r2, #0x61
BEQ hit_gator_body ; hit a
CMP r2, #0x54
BEQ hit_turtle ; hit T
CMP r2, #0x4F
BEQ hit_lily ; hit lily
CMP r2, #0x2B
BEQ hit_fly ; hit +
B collision_check_end
hit_fly
MOV r12, #1 ; update indicator to stationary
MOV r7, #0x2E ; update previous character as .
BL score_fly ; add 100 points for hitting fly
B collision_check_end
hit_lily
MOV r12, #3 ; update indicator to move left
MOV r7, #0x4F ; update previous character as O
B collision_check_end
hit_turtle
MOV r12, #3 ; update indicator to move left
MOV r7, #0x54 ; update previous character to T
B collision_check_end
hit_gator_body
MOV r12, #3 ; indicator to move frog right
MOV r7, #0x61 ; save "a" for frog is on gator body
B collision_check_end
hit_dot
MOV r12, #1 ; update indicator to be stationary
MOV r7, #0x2E ; update previous character to .
B collision_check_end
hit_space
MOV r12, #1 ; update indicator to be stationary
MOV r7, #0x20 ; update previous character to "space"
B collision_check_end
hit_water
MOV r12, #1 ; upadate indicator to stationary
MOV r7, #0x20 ; update previous character to space
SUB r10, r10, #1 ; minus life
BL illuminate_LEDs ; update LEDs
MOV r4, #0x02C7
MOVT r4, #0x2000
B collision_check_end
hit_car
MOV r12, #1 ; update indicator to stationary
SUB r10, r10, #1 ; minus life
BL illuminate_LEDs ; update LEDs
MOV r4, #0x02BE ; respawn address
MOVT r4, #0x2000
B collision_check_end
hit_truck
MOV r12, #1 ; update indicator to stationary
SUB r10, r10, #1 ; minus life
BL illuminate_LEDs ; update LEDs
MOV r4, #0x02B4 ; respawn address
MOVT r4, #0x2000
B collision_check_end
hit_asterisk
MOV r12, #3 ; update indicator to move left
ADD r4, r4, #49 ; put back frog
B collision_check_end
hit_border
MOV r7, #0x20 ; update previous character to "space"
MOV r12, #1 ; update indicator to stationary
SUB r10, r10, #1 ; minus life
BL illuminate_LEDs ; update LEDs
MOV r4, #0x02C5 ; respawn address
MOVT r4, #0x2000
B collision_check_end
hit_border_dash
MOV r12, #1 ; update indicator to stationary
SUB r4, r4, #49 ; doesnt allow frog to go into bottom border
B collision_check_end
hit_gator_head
MOV r7, #0x20 ; update previous character to space
MOV r12, #1 ; update indicator to stationary
SUB r10, r10, #1 ; minus life
BL illuminate_LEDs ; update LEDs
MOV r4, #0x02C3 ; respawn address
MOVT r4, #0x2000
B collision_check_end
hit_log
MOV r12, #2 ; update indicator to move right
MOV r7, #0x4C ; update previous character to L
B collision_check_end
collision_check_end
LDMFD SP!, {lr}
MOV pc, lr
read_character:
STMFD SP!, {lr}
MOV r2, #0xC000
MOVT r2, #0x4000
MOV r0, #0x0000
MOVT r0, #0x2000
LDRB r3, [r2,#U0LSR] ; load status register RxFE
MOV r5, #0x10
AND r3, r3, r5 ; mask status register to test for 1 or 0
CMP r3, r5 ; compare for 0 or 1
BEQ read_character ; if equal 0 loop back
LDRB r1, [r2] ; Read key from Recieve Register
; CMP r6, #4
; BEQ game_over_button
; CMP r6, #3
; BEQ pause_unpause ; if in paused state ignore key press, check only for unpause
CMP r1, #0x77 ; branch if key press = w
BEQ key_w
CMP r1, #0x61 ; branch if key press = a
BEQ key_a
CMP r1, #0x73 ; branch if key press = s
BEQ key_s
CMP r1, #0x64 ; branch if key press = d
BEQ key_d
; CMP r1, #0x6A
; BEQ key_j
; CMP r1, #0x6B
; BEQ key_k
;pause_unpause
; CMP r1, #0x68 ; use h for pause state
; BEQ key_h
; CMP r1, #0x6B
; BEQ key_k
; B end_key ; other key, ignore
;game_over_button
; CMP r1, #0x6B
; BEQ key_k
B end_key
;key_k
; BL reset_game
; B end_key
;key_j
; LDR r0, ptr
; BL print_board
; B start_game
key_w
STRB r7, [r4] ; input previous object in old frog postion
SUB r4, r4, #49 ; next position for frog
LDRB r2, [r4]
BL collision_check
MOV r1, #0x26
STRB r1, [r4] ; store frog in new position
MOV r1, #0x037B
MOVT r1, #0x2000 ; tenth position of score
LDRB r0, [r1] ; read current value of tenth position of score
CMP r0, #0x39 ; is the value '9'?
BEQ score_tenth
ADD r0, r0, #1
STRB r0, [r1]
B not_score_nine
score_tenth
MOV r0, #0x30 ; if value is '9' reset to 0
STRB r0, [r1]
SUB r1, r1, #1 ; go to 100th place
LDRB r0, [r1] ; read 100th place value
CMP r0, #0x39 ; compare it to 9
BEQ score_hundredth
ADD r0, r0, #1
STRB r0, [r1]
B not_score_nine
score_hundredth
MOV r0, #0x30 ; if 100th place is 9 change to 0
STRB r0, [r1]
SUB r1, r1, #1 ; go to 1000th place
LDRB r0, [r1]
ADD r0, r0, #1
STRB r0, [r1]
not_score_nine
;CMP r6, #1
;BEQ start_game
B end_key
key_a
STRB r7, [r4] ; input previous object in old frog postion
SUB r4, r4, #1 ; next position for frog
LDRB r2, [r4]
BL collision_check
MOV r1, #0x26
STRB r1, [r4] ; store frog in new position
B end_key
key_s
STRB r7, [r4] ; input previous object in old frog postion
ADD r4, r4, #49 ; next position for frog
LDRB r2, [r4]
BL collision_check
MOV r1, #0x26
STRB r1, [r4] ; store frog in new position
;CMP r6, #1
;BEQ start_game
B end_key
key_d
STRB r7, [r4] ; input previous object in old frog postion
ADD r4, r4, #1 ; next position for frog
LDRB r2, [r4]
BL collision_check
MOV r1, #0x26
STRB r1, [r4] ; store frog in new position
MOV r0, #0x027E
MOVT r0, #0x2000
MOV r1, #0x43
STRB r1, [r0]
B end_key
;key_h
; CMP r6, #3
; BEQ unpause
; MOV r6, #3
; BL illuminate_RGB_LED
; BL pause_screen
; B end_key
;unpause
; MOV r6, #2
; BL illuminate_RGB_LED
; B end_key
;start_game
; MOV r6, #2
; BL illuminate_RGB_LED
; BL timer_init
end_key
LDMFD SP!, {lr}
MOV pc, lr
reset_game:
STMFD SP!, {lr}
MOV r0, #0x0000
MOVT r0, #0x2000
LDR r1, reset_ptr ; reset board address
reset_game_loop
LDRB r2, [r1] ; load byte of reset board
CMP r2, #0x00 ; if null found branch
BEQ reset_null
STRB r2, [r0] ; if not update game board from reset board
ADD r0, r0, #1 ; increment address
ADD r1, r1, #1 ; increment address
B reset_game_loop
reset_null
STRB r2, [r0] ; store null
MOV r0, #0xED0C
MOVT r0, #0xE000 ; reset register
MOV r1, #0x0004 ; bit 2 = system reset request
MOVT r1, #0xFA05 ; vectkey, must write FA05 to write to reset register
LDR r2, [r0]
ORR r1, r1, r2
STR r1, [r0]
B frogger
LDMFD SP!, {lr}
MOV pc, lr
read_from_keypad:
STMFD SP!, {lr}
MOV r1, #0x43FC
MOVT r1, #0x4000 ; r1 = 0x400043FC, port A data register
LDRB r3, [r1] ; load byte of port A data register
MOV r1, #0x3C
AND r3, r3, r1
CMP r3, #0
BEQ read_from_keypad ; loop back to read_from_keypad until find a 1 in the pins
MOV r5, r3 ; Copy port A bits to r5
MOV r1, #0x73FC
MOVT r1, #0x4000 ; r1 = 0x400073FC port D data register
MOV r2, #1 ; r2 = 0001
STRB r2, [r1] ; D0 row set high
MOV r1, #0x43FC
MOVT r1, #0x4000 ; r1 = 0x400043FC, port A data register
LDRB r3, [r1] ; read port A pins
AND r2, r3, r5 ; AND current A pins to saved value
CMP r2, r5
BEQ row_one ; If AND value matches, key found in row 1
B read_from_keypad_end
row_one
CMP r6, #4
BEQ game_over_key
CMP r6, #3
BEQ pUP ; if in paused state ignore key press, check only for unpause or restart
CMP r2, #4
BEQ key_one ; if byte = 4, key 1 pressed
CMP r2, #0x10
BEQ key_three ; if byte = 0x10, key 3 pressed
pUP
CMP r2, #8
BEQ key_two ; if byte = 8, key 2 pressed
CMP r2, #0x10 ; if byte = 0x10 key 3 pressed
BEQ key_three
B read_from_keypad_end
game_over_key
CMP r2, #0x10
BEQ key_three
B read_from_keypad_end
key_one
BL uart_init
LDR r0, ptr
BL print_board
MOV r1, #0x73FC
MOVT r1, #0x4000 ; r1 = 0x400073FC port D data register
MOV r2, #0xF ; r2 = 1111
STRB r2, [r1] ; enable all D pins again
B key_one_start
key_one_start
MOV r6, #2
BL illuminate_RGB_LED
BL timer_init
B read_from_keypad_end
key_two
BL uart_init
MOV r1, #0x73FC
MOVT r1, #0x4000 ; r1 = 0x400073FC port D data register
MOV r2, #0xF ; r2 = 1111
STRB r2, [r1] ; enable all D pins again
CMP r6, #3
BEQ unpause_game
MOV r6, #3
BL illuminate_RGB_LED
BL pause_screen
B read_from_keypad_end
unpause_game
MOV r6, #2
BL illuminate_RGB_LED
B read_from_keypad_end
key_three
BL uart_init
MOV r1, #0x73FC
MOVT r1, #0x4000 ; r1 = 0x400073FC port D data register
MOV r2, #0xF ; r2 = 1111
STRB r2, [r1] ; enable all D pins again
BL reset_game
B read_from_keypad_end
read_from_keypad_end
LDMFD SP!, {lr}
MOV pc, lr
pause_screen:
STMFD SP!, {lr}
LDR r0, pause_ptr ; load pointer to pause string
pause_screen_loop
LDRB r1, [r0]
CMP r1, #0x00
BEQ pause_screen_end
BL output_character ; print pause prompt
ADD r0, r0, #1
B pause_screen_loop
pause_screen_end
LDMFD SP!, {lr}
MOV pc, lr
gameover_screen:
STMFD SP!, {lr}
MOV r1, #0x0C
BL output_character
MOV r10, #5
MOV r6, #4
BL illuminate_RGB_LED ; light RGB to blue
LDR r0, go
gameover_screen_loop
LDRB r1, [r0]
CMP r1, #0x00
BEQ gameover_screen_end
BL output_character ; print game over prompt
ADD r0, r0, #1
B gameover_screen_loop
gameover_screen_end
LDR r0, score_ptr ; loop to display score in gameover screen
display_score_loop
LDRB r1, [r0]
CMP r1, #0x00
BEQ display_score_loop_end
BL output_character
ADD r0, r0, #1
B display_score_loop
display_score_loop_end
MOV r1, #0x0A
BL output_character
MOV r1, #0x0D
BL output_character
LDMFD SP!, {lr}
MOV pc, lr
game_time: ; this changes the characters for the game timer on screen
STMFD SP!, {lr}
MOV r0, #0x0315
MOVT r0, #0x2000 ; tenth place
gametime_loop
LDRB r1, [r0] ; load tenth place digit
CMP r1, #0x30
BEQ time_tenth_zero ; if tenth place = 0, branch
tenth_loop
MOV r0, #0x0316
MOVT r0, #0x2000 ; if not load ones place
LDRB r1, [r0]
CMP r1, #0x30
BEQ time_one_zero ; if ones place = 0, branch
SUB r1, r1, #1 ; decrement ones place digit
STRB r1, [r0]
B gametime_end
time_one_zero ; if ones place is 0
MOV r1, #0x39
STRB r1, [r0] ; change ones place to 9
MOV r0, #0x0315
MOVT r0, #0x2000 ; tenth place
LDRB r1, [r0]
SUB r1, r1, #1 ; decrement tenth place
STRB r1, [r0]
B gametime_end
time_tenth_zero
MOV r0, #0x0316
MOVT r0, #0x2000 ; ones digit
LDRB r1, [r0]
CMP r1, #0x30
BEQ gameover_screen ; branch to gameover screen if both digits of timer = 0
B tenth_loop
gametime_end
LDMFD SP!, {lr}
MOV pc, lr
spawn_car: ; 0x200001BA, 0x2000027E
STMFD SP!, {lr}
MOV r1, #0x43
STRB r1, [r0] ; stores new car
LDMFD SP!, {lr}
MOV pc, lr
spawn_truck: ; 0x200001B5, 0x20000248
STMFD SP!, {lr}
MOV r1, #0x23
STRB r1, [r0] ; stores new truck
LDMFD SP!, {lr}
MOV pc, lr
spawn_log: ; 0x20000127, 0x200000C5
STMFD SP!, {lr}
MOV r1, #0x4C
STRB r1, [r0] ; stores new log
LDMFD SP!, {lr}
MOV pc, lr
spawn_turtle: ; 0x20000122
STMFD SP!, {lr}
MOV r1, #0x54
STRB r1, [r0] ; stores new turtle
LDMFD SP!, {lr}
MOV pc, lr
spawn_lily: ; 0x20000122, 0x200000C0
STMFD SP!, {lr}
MOV r1, #0x4F
STRB r1, [r0] ; stores new lily
LDMFD SP!, {lr}
MOV pc, lr
spawn_gator_head: ; 0x20000122, 0x200000C0
STMFD SP!, {lr}
MOV r1, #0x41
STRB r1, [r0] ; stores new gator head
LDMFD SP!, {lr}
MOV pc, lr
spawn_gator_body: ; 0x20000122, 0x200000C0
STMFD SP!, {lr}
MOV r1, #0x61
STRB r1, [r0] ; stores new gator body
LDMFD SP!, {lr}
MOV pc, lr
spawn_fly:
STMFD SP!, {lr}
MOV r1, #0x2B
STRB r1, [r0] ; stores fly
LDMFD SP!, {lr}
MOV pc, lr
add_home_score: ; adding 50 points for return frog home
STMFD SP!, {lr}
MOV r0, #0x037B
MOVT r0, #0x2000 ; tenth place of score
LDRB r1, [r0] ; load digit
CMP r1, #0x34
BLE tenth_le_four
CMP r1, #0x39
BEQ score_hundred_place ; branch if tenth place = 9
CMP r1, #0x35
BEQ hundred_five ; branch if tenth place = 5
CMP r1, #0x36
BEQ hundred_six ; branch if tenth place = 6
CMP r1, #0x37
BEQ hundred_seven ; branch if tenth place = 7
CMP r1, #0x38
BEQ hundred_eight ; branch if tenth place = 8
B add_home_score_end
hundred_eight
MOV r1, #0x33
STRB r1, [r0] ; store 3 in tenth place
SUB r0, r0, #1 ; go to hundred place
LDRB r1, [r0]
CMP r1, #0x39
BEQ score_thousandth_place ; branch if hundred place is 9
ADD r1, r1, #1 ; if not add one
STRB r1, [r0] ; update hundred place
B add_home_score_end
hundred_seven
MOV r1, #0x32
STRB r1, [r0] ; store 2 in tenth place
SUB r0, r0, #1 ; go to hundred place
LDRB r1, [r0]
CMP r1, #0x39
BEQ score_thousandth_place ; branch if hundred place if 9
ADD r1, r1, #1 ; if not add one
STRB r1, [r0]
B add_home_score_end
hundred_six
MOV r1, #0x31
STRB r1, [r0] ; store 1 in tenth place
SUB r0, r0, #1 ; go to hundred place
LDRB r1, [r0]
CMP r1, #0x39
BEQ score_thousandth_place ; branch if hundred place is 9
ADD r1, r1, #1 ; if not add one
STRB r1, [r0]
B add_home_score_end
hundred_five
MOV r0, #0x30
STRB r1, [r0] ; store 0 in tenth place
SUB r0, r0, #1 ; go to hundreth place
LDRB r1, [r0]
CMP r1, #0x39 ; if hundreth place = 9 branch
BEQ score_thousandth_place
ADD r1, r1, #1
STRB r1, [r0] ; increment hundreth place by 1
B add_home_score_end
tenth_le_four
ADD r1, r1, #5
STRB r1, [r0]
B add_home_score_end
score_hundred_place
MOV r1, #0x34
STRB r1, [r0] ; store 4 in tenth place
SUB r0, r0, #1 ; go to hundreth place
LDRB r1, [r0]
CMP r1, #0x39 ; is hundreth place = 9
BEQ score_thousandth_place
ADD r1, r1, #1
STRB r1, [r0] ; if hundreth place not 9, increment by 1
B add_home_score_end
score_thousandth_place
MOV r1, #0x30
STRB r1, [r0]
SUB r0, r0, #1 ; go to thousandth place
LDRB r1, [r0]
CMP r1, #0x39
BEQ score_ten_thousand_place
ADD r1, r1, #1 ; increment by 1
STRB r1, [r0]
B add_home_score_end
score_ten_thousand_place
MOV r1, #0x30
STRB r1, [r0]
SUB r0, r0, #1
LDRB r1, [r0]
ADD r1, r1, #1
STRB r1, [r0]
B add_home_score_end
add_home_score_end
LDMFD SP!, {lr}
MOV pc, lr
add_level_score: ; add 250 points for advancing level
STMFD SP!, {lr}
MOV r0, #0x037B
MOVT r0, #0x2000 ; tenth place of score
LDRB r1, [r0] ; load digit
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, #5 ; add 5 for the 50 points
CMP r1, #9
BLE ten_nine ; branch if sum of tenth place and 5 is less than equal 9
SUB r1, r1, #10 ; take difference from 10
ADD r1, r1, #48 ; convert difference to char
STRB r1, [r0] ; store tenth place plus 50 points
SUB r0, r0, #1 ; go to hundreds place
LDRB r1, [r0]
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, #3 ; add 2 plus from carry
CMP r1, #9
BLE hundred_nine ; branch if sum of hundred digit plus points < 9
SUB r1, r1, #10 ; take difference from 10
ADD r1, r1, #48
STRB r1, [r0]
SUB r0, r0, #1 ; go to thousand place
LDRB r1, [r0] ; load thousand number
ADD r1, r1, #1
CMP r1, #9
BLE thousand_nine
SUB r1, r1, #10
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store thousand place
SUB r0, r0, #1 ; 10 thousand place
LDRB r1, [r0]
ADD r1, r1, #1 ; increment 10 thousand place
STRB r1, [r0]
B add_level_score_end
ten_nine
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store sum to tenth place
SUB r0, r0, #1 ; move to hundreds place
LDRB r1, [r0] ; load hundreds digit
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, #2
CMP r1, #9
BLE hundred_nine ; branch if sum hundreds place and 2 is less than equal 9
SUB r1, r1, #10 ; if sum greater than 9 take difference of 10
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store difference in hundreds place
SUB r0, r0, #1 ; go to thousands place
LDRB r2, [r0] ; load thousands digit
SUB r2, r2, #48 ; convert to decimal
ADD r2, r2, #1 ; sum thousands place plus carry
CMP r2, #9
BLE thousand_nine
SUB r2, r2, #10 ; take difference
STRB r2, [r0] ; store in thousand place
SUB r0, r0, #1 ; 10 thousand place
LDRB r1, [r0]
ADD r1, r1, #1 ; increment 10 thousand place
STRB r1, [r0]
B add_level_score_end
hundred_nine
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; update plus the 200 points
B add_level_score_end
thousand_nine
ADD r2, r2, #48 ; convert to char
STRB r2, [r0]
add_level_score_end
LDMFD SP!, {lr}
MOV pc, lr
unused_time: ; address 1st digit of timer = 20000315, 20000316 address of Score: 20000378, 0379, 037A, 037B, 037C
; multiplies time left by 10 and add to score accordingly
STMFD SP!, {lr}
MOV r0, #0x0316
MOVT r0, #0x2000
LDRB r1, [r0] ; load ones digit of time
SUB r1, r1, #48 ; convert to decimal
MOV r0, #0x037B
MOVT r0, #0x2000
LDRB r2, [r0] ; load score tenth digit
SUB r2, r2, #48 ; convert to decimal
ADD r1, r1, r2 ; add numbers
CMP r1, #9
BLE less_nine ; branch if sum is less than or equal to nine
SUB r1, r1, #10 ; take ones digit of sum
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store difference to tenth place of score
MOV r0, #0x0315
MOVT r0, #0x2000
LDRB r2, [r0] ; load tenths place of time
ADD r2, r2, #1 ; add one from carry over
SUB r2, r2, #48 ; convert to decimal
MOV r0, #0x037A
MOVT r0, #0x2000 ; hundreds place of score
LDRB r1, [r0] ; load digit of hundreds place
SUB r1, r1, #48 ; convert to decimal
ADD r1, r1, r2 ; sum hundreds place of score and tenth place of time + 1
CMP r2, #9
BLE hun_nine
SUB r1, r1, #10 ; r1 = difference of sum - 10
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store difference in hundreds place of score
SUB r0, r0, #1 ; go to thousands place
LDRB r1, [r0] ; get thousandth digit
ADD r1, r1, #1 ; add one
STRB r1, [r0] ; store
B unused_time_loop_end
less_nine
ADD r1, r1, #48 ; convert sum to character
STRB r1, [r0] ; store tenth digit
MOV r0, #0x0315
MOVT r0, #0x2000 ; tenth digit of time
LDRB r1, [r0]
SUB r1, r1, #48 ; convert to decimal
MOV r0, #0x037A
MOVT r0, #0x2000 ; hundreds digit of score
LDRB r2, [r0]
SUB r2, r2, #48 ; convert to decimal
ADD r1, r1, r2 ; sum numbers together
CMP r1, #9
BLE hun_nine ; branch if sum is less than or equal to nine
SUB r1, r1, #10
ADD r1, r1, #48 ; convert to char
STRB r1, [r0] ; store difference to hundreds place
SUB r0, r0, #1 ; move to thousands place
LDRB r2, [r0]
ADD r2, r2, #1 ; add one to thousands place
STRB r2, [r0]
B unused_time_loop_end
hun_nine
ADD r1, r1, #48 ; convert to character
STRB r1, [r0] ; store tenth place of time * 10 to hundreds place of score
unused_time_loop_end
LDMFD SP!, {lr}
MOV pc, lr
check_home:
STMFD SP!, {lr}
; Home slots: 68, 69, 6A, 6B, 6C
; 72, 73, 74, 75, 76
; 7C, 7D, 7E, 7F, 80
; 86, 87, 88, 89, 8A
MOV r0, #0x0068
MOVT r0, #0x2000
MOV r2, #0x48
check_first_home_loop
LDRB r1, [r0]
ADD r0, r0, #1
CMP r1, #0x26
BEQ print_H_first ; is there a frog in home slot?
CMP r1, #0x2A
BNE check_first_home_loop
MOV r0, #0x0072
MOVT r0, #0x2000
B check_second_home_loop
print_H_first ; prints H in respective 5 slots, first home
MOV r0, #0x0068
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x0069
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x006A
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x006B
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x006C
MOVT r0, #0x2000
STRB r2, [r0]
MOV r4, #0x02D0
MOVT r4, #0x2000
MOV r1, #0x26
STRB r1, [r4]
BL add_home_score
MOV r12, #1
MOV r7, #0x2E
B check_home_end
check_second_home_loop
LDRB r1, [r0]
ADD r0, r0, #1
CMP r1, #0x26
BEQ print_H_second ; is there a frog in second home slot?
CMP r1, #0x2A
BNE check_second_home_loop
MOV r0, #0x007C
MOVT r0, #0x2000
B check_third_home_loop
print_H_second ; prints H in second home slots
MOV r0, #0x0072
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x0073
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x0074
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x0075
MOVT r0, #0x2000
STRB r2, [r0]
MOV r0, #0x0076
MOVT r0, #0x2000
STRB r2, [r0]
MOV r4, #0x02D4
MOVT r4, #0x2000
MOV r1, #0x26