-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.axf.objdump
2741 lines (2543 loc) · 97.1 KB
/
main.axf.objdump
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
D:/OneDrive/ECE243/project/ReCrossy-Road/main.axf: file format elf32-littlearm
Disassembly of section .vectors:
00000000 <__cs3_interrupt_vector>:
0: 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 ................
10: 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 ................
20: 5c 02 00 00 60 02 00 00 64 02 00 00 68 02 00 00 \...`...d...h...
30: 6c 02 00 00 58 19 00 00 b8 03 00 00 70 02 00 00 l...X.......p...
Disassembly of section .text:
00000040 <__cs3_reset_generic>:
40: ea000026 b e0 <__cs3_start_asm_sim>
00000044 <__cs3_start_c>:
44: e59f608c ldr r6, [pc, #140] ; d8 <__cs3_start_c+0x94>
48: e3560000 cmp r6, #0
4c: e92d4080 push {r7, lr}
50: e2466001 sub r6, r6, #1
54: 0a00001e beq d4 <__cs3_start_c+0x90>
58: e59f507c ldr r5, [pc, #124] ; dc <__cs3_start_c+0x98>
5c: e3a00000 mov r0, #0
60: e3a01000 mov r1, #0
64: e515200c ldr r2, [r5, #-12]
68: e515e010 ldr lr, [r5, #-16]
6c: e5154008 ldr r4, [r5, #-8]
70: e15e0002 cmp lr, r2
74: 00822004 addeq r2, r2, r4
78: 0a000009 beq a4 <__cs3_start_c+0x60>
7c: e3540000 cmp r4, #0
80: 0a000007 beq a4 <__cs3_start_c+0x60>
84: e1a07002 mov r7, r2
88: e1a0c002 mov r12, r2
8c: e8be000c ldm lr!, {r2, r3}
90: e8ac000c stmia r12!, {r2, r3}
94: e067300c rsb r3, r7, r12
98: e1540003 cmp r4, r3
9c: e1a0200c mov r2, r12
a0: 1afffff9 bne 8c <__cs3_start_c+0x48>
a4: e515e004 ldr lr, [r5, #-4]
a8: e35e0000 cmp lr, #0
ac: 11a03002 movne r3, r2
b0: 0a000003 beq c4 <__cs3_start_c+0x80>
b4: e8a30003 stmia r3!, {r0, r1}
b8: e062c003 rsb r12, r2, r3
bc: e15e000c cmp lr, r12
c0: 1afffffb bne b4 <__cs3_start_c+0x70>
c4: e2466001 sub r6, r6, #1
c8: e3760001 cmn r6, #1
cc: e2855014 add r5, r5, #20
d0: 1affffe3 bne 64 <__cs3_start_c+0x20>
d4: eb000606 bl 18f4 <__cs3_premain>
d8: 00000001 .word 0x00000001
dc: 00001a54 .word 0x00001a54
000000e0 <__cs3_start_asm_sim>:
e0: e28f103c add r1, pc, #60 ; 0x3c
e4: e3a00016 mov r0, #22
e8: ef123456 svc 0x00123456
ec: e3500000 cmp r0, #0
f0: ba000008 blt 118 <__cs3_start_asm_sim+0x38>
f4: e59f2028 ldr r2, [pc, #40] ; 124 <__cs3_heap_start_ptr>
f8: e59fd01c ldr sp, [pc, #28] ; 11c <__cs3_start_asm_sim+0x3c>
fc: e5920008 ldr r0, [r2, #8]
100: e3500000 cmp r0, #0
104: 11a0d000 movne sp, r0
108: e59f1010 ldr r1, [pc, #16] ; 120 <__cs3_start_asm_sim+0x40>
10c: e5920004 ldr r0, [r2, #4]
110: e3500000 cmp r0, #0
114: 15810000 strne r0, [r1]
118: eaffffc9 b 44 <__cs3_start_c>
11c: 3ffffff8 .word 0x3ffffff8
120: 0009f698 .word 0x0009f698
00000124 <__cs3_heap_start_ptr>:
124: 0009f6d0 .word 0x0009f6d0
00000128 <_start>:
128: e51fd000 ldr sp, [pc, #-0] ; 130 <_start+0x8>
12c: eaffffc4 b 44 <__cs3_start_c>
130: 3ffffff8 .word 0x3ffffff8
00000134 <deregister_tm_clones>:
134: e92d4008 push {r3, lr}
138: e59f002c ldr r0, [pc, #44] ; 16c <deregister_tm_clones+0x38>
13c: e59f302c ldr r3, [pc, #44] ; 170 <deregister_tm_clones+0x3c>
140: e0603003 rsb r3, r0, r3
144: e3530006 cmp r3, #6
148: 8a000001 bhi 154 <deregister_tm_clones+0x20>
14c: e8bd4008 pop {r3, lr}
150: e12fff1e bx lr
154: e59f3018 ldr r3, [pc, #24] ; 174 <deregister_tm_clones+0x40>
158: e3530000 cmp r3, #0
15c: 0afffffa beq 14c <deregister_tm_clones+0x18>
160: e1a0e00f mov lr, pc
164: e12fff13 bx r3
168: eafffff7 b 14c <deregister_tm_clones+0x18>
16c: 0009f6a0 .word 0x0009f6a0
170: 0009f6a3 .word 0x0009f6a3
174: 00000000 .word 0x00000000
00000178 <register_tm_clones>:
178: e92d4008 push {r3, lr}
17c: e59f0034 ldr r0, [pc, #52] ; 1b8 <register_tm_clones+0x40>
180: e59f3034 ldr r3, [pc, #52] ; 1bc <register_tm_clones+0x44>
184: e0603003 rsb r3, r0, r3
188: e1a03143 asr r3, r3, #2
18c: e0833fa3 add r3, r3, r3, lsr #31
190: e1b010c3 asrs r1, r3, #1
194: 1a000001 bne 1a0 <register_tm_clones+0x28>
198: e8bd4008 pop {r3, lr}
19c: e12fff1e bx lr
1a0: e59f2018 ldr r2, [pc, #24] ; 1c0 <register_tm_clones+0x48>
1a4: e3520000 cmp r2, #0
1a8: 0afffffa beq 198 <register_tm_clones+0x20>
1ac: e1a0e00f mov lr, pc
1b0: e12fff12 bx r2
1b4: eafffff7 b 198 <register_tm_clones+0x20>
1b8: 0009f6a0 .word 0x0009f6a0
1bc: 0009f6a0 .word 0x0009f6a0
1c0: 00000000 .word 0x00000000
000001c4 <__do_global_dtors_aux>:
1c4: e92d4010 push {r4, lr}
1c8: e59f402c ldr r4, [pc, #44] ; 1fc <__do_global_dtors_aux+0x38>
1cc: e5d43000 ldrb r3, [r4]
1d0: e3530000 cmp r3, #0
1d4: 1a000006 bne 1f4 <__do_global_dtors_aux+0x30>
1d8: ebffffd5 bl 134 <deregister_tm_clones>
1dc: e59f301c ldr r3, [pc, #28] ; 200 <__do_global_dtors_aux+0x3c>
1e0: e3530000 cmp r3, #0
1e4: 159f0018 ldrne r0, [pc, #24] ; 204 <__do_global_dtors_aux+0x40>
1e8: 1320f000 nopne {0}
1ec: e3a03001 mov r3, #1
1f0: e5c43000 strb r3, [r4]
1f4: e8bd4010 pop {r4, lr}
1f8: e12fff1e bx lr
1fc: 0009f6a0 .word 0x0009f6a0
200: 00000000 .word 0x00000000
204: 000019e4 .word 0x000019e4
00000208 <frame_dummy>:
208: e92d4008 push {r3, lr}
20c: e59f3034 ldr r3, [pc, #52] ; 248 <frame_dummy+0x40>
210: e3530000 cmp r3, #0
214: 159f0030 ldrne r0, [pc, #48] ; 24c <frame_dummy+0x44>
218: 159f1030 ldrne r1, [pc, #48] ; 250 <frame_dummy+0x48>
21c: 1320f000 nopne {0}
220: e59f002c ldr r0, [pc, #44] ; 254 <frame_dummy+0x4c>
224: e5903000 ldr r3, [r0]
228: e3530000 cmp r3, #0
22c: 0a000003 beq 240 <frame_dummy+0x38>
230: e59f3020 ldr r3, [pc, #32] ; 258 <frame_dummy+0x50>
234: e3530000 cmp r3, #0
238: 11a0e00f movne lr, pc
23c: 112fff13 bxne r3
240: e8bd4008 pop {r3, lr}
244: eaffffcb b 178 <register_tm_clones>
248: 00000000 .word 0x00000000
24c: 000019e4 .word 0x000019e4
250: 0009f6a4 .word 0x0009f6a4
254: 00001a58 .word 0x00001a58
258: 00000000 .word 0x00000000
0000025c <__cs3_reset>:
return;
}
// Define the remaining exception handlers
void __attribute__((interrupt)) __cs3_reset(void) {
25c: eafffffe b 25c <__cs3_reset>
00000260 <__cs3_isr_undef>:
while (1);
}
void __attribute__((interrupt)) __cs3_isr_undef(void) {
260: eafffffe b 260 <__cs3_isr_undef>
00000264 <__cs3_isr_swi>:
while (1);
}
void __attribute__((interrupt)) __cs3_isr_swi(void) {
264: eafffffe b 264 <__cs3_isr_swi>
00000268 <__cs3_isr_pabort>:
while (1);
}
void __attribute__((interrupt)) __cs3_isr_pabort(void) {
268: eafffffe b 268 <__cs3_isr_pabort>
0000026c <__cs3_isr_dabort>:
while (1);
}
void __attribute__((interrupt)) __cs3_isr_dabort(void) {
26c: eafffffe b 26c <__cs3_isr_dabort>
00000270 <__cs3_isr_fiq>:
while (1);
}
void __attribute__((interrupt)) __cs3_isr_fiq(void) {
270: eafffffe b 270 <__cs3_isr_fiq>
00000274 <set_A9_IRQ_stack>:
{
int stack, mode;
stack = A9_ONCHIP_END - 7; // top of A9 onchip memory, aligned to 8 bytes
/* change processor to IRQ mode with interrupts disabled */
mode = INT_DISABLE | IRQ_MODE;
asm("msr cpsr, %[ps]" : : [ps] "r" (mode));
274: e3a030d2 mov r3, #210 ; 0xd2
278: e129f003 msr CPSR_fc, r3
/* set banked stack pointer */
asm("mov sp, %[ps]" : : [ps] "r" (stack));
27c: e3e03007 mvn r3, #7
280: e1a0d003 mov sp, r3
/* go back to SVC mode before executing subroutine return! */
mode = INT_DISABLE | SVC_MODE;
asm("msr cpsr, %[ps]" : : [ps] "r" (mode));
284: e3a030d3 mov r3, #211 ; 0xd3
288: e129f003 msr CPSR_fc, r3
28c: e12fff1e bx lr
00000290 <enable_A9_interrupts>:
* Turn on interrupts in the ARM processor
*/
void enable_A9_interrupts(void)
{
int status = SVC_MODE | INT_ENABLE;
asm("msr cpsr,%[ps]" : : [ps]"r"(status));
290: e3a03053 mov r3, #83 ; 0x53
294: e129f003 msr CPSR_fc, r3
298: e12fff1e bx lr
0000029c <config_KEYs>:
}
/* setup the KEY interrupts in the FPGA */
void config_KEYs() {
volatile int *KEY_ptr = (int *) KEY_BASE; // pushbutton KEY address
*(KEY_ptr + 2) = 0x3; // enable interrupts for KEY[1]
29c: e3a03000 mov r3, #0
2a0: e34f3f20 movt r3, #65312 ; 0xff20
2a4: e3a02003 mov r2, #3
2a8: e5832058 str r2, [r3, #88] ; 0x58
2ac: e12fff1e bx lr
000002b0 <config_PS2>:
}
/* setup the PS/2 interrupts */
void config_PS2() {
volatile int * PS2_ptr = (int *)PS2_BASE; // PS/2 port address
*(PS2_ptr) = 0xFF; /* reset */
2b0: e3a03000 mov r3, #0
2b4: e34f3f20 movt r3, #65312 ; 0xff20
2b8: e3a020ff mov r2, #255 ; 0xff
2bc: e5832100 str r2, [r3, #256] ; 0x100
*(PS2_ptr + 1) =
2c0: e3a02001 mov r2, #1
2c4: e5832104 str r2, [r3, #260] ; 0x104
2c8: e12fff1e bx lr
000002cc <pushbutton_ISR>:
0x1; /* write to the PS/2 Control register to enable interrupts */
}
void pushbutton_ISR(void) {
volatile int *KEY_ptr = (int *) KEY_BASE;
int press;
press = *(KEY_ptr + 3); // read the pushbutton interrupt register
2cc: e3a03000 mov r3, #0
2d0: e34f3f20 movt r3, #65312 ; 0xff20
2d4: e593205c ldr r2, [r3, #92] ; 0x5c
*(KEY_ptr + 3) = press; // Clear the interrupt
2d8: e583205c str r2, [r3, #92] ; 0x5c
key_dir ^= 1; // Toggle key_dir value
2dc: e30f36bc movw r3, #63164 ; 0xf6bc
2e0: e3403009 movt r3, #9
2e4: e5932000 ldr r2, [r3]
2e8: e2222001 eor r2, r2, #1
2ec: e5832000 str r2, [r3]
2f0: e12fff1e bx lr
000002f4 <PS2_ISR>:
void PS2_ISR(void) {
volatile int * PS2_ptr = (int *) 0xFF200100; // PS/2 port address
int PS2_data, RAVAIL;
PS2_data = *(PS2_ptr); // read the Data register in the PS/2 port
2f4: e3a03000 mov r3, #0
2f8: e34f3f20 movt r3, #65312 ; 0xff20
2fc: e5932100 ldr r2, [r3, #256] ; 0x100
RAVAIL = (PS2_data & 0xFFFF0000) >> 16; // extract the RAVAIL field
if (RAVAIL > 0)
300: e1b03822 lsrs r3, r2, #16
304: 012fff1e bxeq lr
{
/* always save the last three bytes received */
byte1 = byte2;
308: e30f36bc movw r3, #63164 ; 0xf6bc
30c: e3403009 movt r3, #9
310: e5d31005 ldrb r1, [r3, #5]
314: e5c31004 strb r1, [r3, #4]
byte2 = byte3;
318: e5d31006 ldrb r1, [r3, #6]
31c: e5c31005 strb r1, [r3, #5]
byte3 = PS2_data & 0xFF;
320: e6ef2072 uxtb r2, r2
324: e5c32006 strb r2, [r3, #6]
if ((byte2 == (char) 0xE0) && (byte3 == (char) 0x75)) {
328: e35100e0 cmp r1, #224 ; 0xe0
32c: 112fff1e bxne lr
330: e3520075 cmp r2, #117 ; 0x75
334: 1a000004 bne 34c <PS2_ISR+0x58>
KEYBOARD_UP = true;
338: e30f36bc movw r3, #63164 ; 0xf6bc
33c: e3403009 movt r3, #9
340: e3a02001 mov r2, #1
344: e5c32007 strb r2, [r3, #7]
348: e12fff1e bx lr
} else if((byte2 == (char) 0xE0) && (byte3 == (char) 0x72)){
34c: e3520072 cmp r2, #114 ; 0x72
350: 1a000004 bne 368 <PS2_ISR+0x74>
KEYBOARD_DOWN = true;
354: e30f36bc movw r3, #63164 ; 0xf6bc
358: e3403009 movt r3, #9
35c: e3a02001 mov r2, #1
360: e5c32008 strb r2, [r3, #8]
364: e12fff1e bx lr
} else if((byte2 == (char) 0xE0) && (byte3 == (char) 0x6B)){
368: e352006b cmp r2, #107 ; 0x6b
36c: 1a000004 bne 384 <PS2_ISR+0x90>
KEYBOARD_LEFT = true;
370: e30f36bc movw r3, #63164 ; 0xf6bc
374: e3403009 movt r3, #9
378: e3a02001 mov r2, #1
37c: e5c32009 strb r2, [r3, #9]
380: e12fff1e bx lr
} else if((byte2 == (char) 0xE0) && (byte3 == (char) 0x74)){
384: e3520074 cmp r2, #116 ; 0x74
388: 1a000004 bne 3a0 <PS2_ISR+0xac>
KEYBOARD_RIGHT = true;
38c: e30f36bc movw r3, #63164 ; 0xf6bc
390: e3403009 movt r3, #9
394: e3a02001 mov r2, #1
398: e5c3200a strb r2, [r3, #10]
39c: e12fff1e bx lr
} else if((byte2 == (char) 0xE0) && (byte3 == (char) 0x69)){
3a0: e3520069 cmp r2, #105 ; 0x69
KEYBOARD_RESTART = true;
3a4: 030f36bc movweq r3, #63164 ; 0xf6bc
3a8: 03403009 movteq r3, #9
3ac: 03a02001 moveq r2, #1
3b0: 05c3200b strbeq r2, [r3, #11]
3b4: e12fff1e bx lr
000003b8 <__cs3_isr_irq>:
void PS2_ISR();
// Define the IRQ exception handler
void __attribute__ ((interrupt)) __cs3_isr_irq (void)
{
3b8: e24ee004 sub lr, lr, #4
3bc: e92d500f push {r0, r1, r2, r3, r12, lr}
// Read the ICCIAR from the processor interface
int address = MPCORE_GIC_CPUIF + ICCIAR;
int int_ID = *((int *) address);
3c0: e3e03a13 mvn r3, #77824 ; 0x13000
if (int_ID == PS2_IRQ) // check if interrupt is from the PS/2
3c4: e5133ef3 ldr r3, [r3, #-3827] ; 0xfffff10d
3c8: e353004f cmp r3, #79 ; 0x4f
3cc: 1a000004 bne 3e4 <__cs3_isr_irq+0x2c>
PS2_ISR ();
3d0: ebffffc7 bl 2f4 <PS2_ISR>
else
while (1); // if unexpected, then halt
// Write to the End of Interrupt Register (ICCEOIR)
address = MPCORE_GIC_CPUIF + ICCEOIR;
*((int *) address) = int_ID;
3d4: e3a0204f mov r2, #79 ; 0x4f
3d8: e3e03a13 mvn r3, #77824 ; 0x13000
3dc: e5032eef str r2, [r3, #-3823] ; 0xfffff111
3e0: e8fd900f ldm sp!, {r0, r1, r2, r3, r12, pc}^
3e4: eafffffe b 3e4 <__cs3_isr_irq+0x2c>
000003e8 <hw_write_bits>:
address = MPCORE_GIC_DIST + addr_offset;
hw_write_bits((int *) address, 0x1 << (int_ID & 0x1f), value);
}
void hw_write_bits(volatile int * addr, volatile int unmask, volatile int value)
{
3e8: e24dd008 sub sp, sp, #8
3ec: e58d1004 str r1, [sp, #4]
3f0: e58d2000 str r2, [sp]
*addr = ((~unmask) & *addr) | value;
3f4: e59d1004 ldr r1, [sp, #4]
3f8: e5903000 ldr r3, [r0]
3fc: e59d2000 ldr r2, [sp]
400: e1c33001 bic r3, r3, r1
404: e1833002 orr r3, r3, r2
408: e5803000 str r3, [r0]
}
40c: e28dd008 add sp, sp, #8
410: e12fff1e bx lr
00000414 <config_interrupt>:
/*
* Configure registers in the GIC for individual interrupt IDs.
*/
void config_interrupt (int int_ID, int CPU_target)
{
414: e92d4010 push {r4, lr}
418: e1a04000 mov r4, r0
* addr_offet = #ICDIPTR + n
* value = CPU_target << ((int_ID & 0x3) * 8)
*/
n = (int_ID >> 2) << 2;
addr_offset = ICDIPTR + n;
value = CPU_target << ((int_ID & 0x3) << 3);
41c: e2003003 and r3, r0, #3
420: e1a03183 lsl r3, r3, #3
/* Set Interrupt Processor Targets Register (ICDIPTRn) to cpu0.
* n = integer_div(int_ID / 4) * 4
* addr_offet = #ICDIPTR + n
* value = CPU_target << ((int_ID & 0x3) * 8)
*/
n = (int_ID >> 2) << 2;
424: e3c00003 bic r0, r0, #3
addr_offset = ICDIPTR + n;
value = CPU_target << ((int_ID & 0x3) << 3);
428: e1a02311 lsl r2, r1, r3
/* Now that we know the register address and value, we need to set the correct bits in
* the GIC register, without changing the other bits */
address = MPCORE_GIC_DIST + addr_offset;
hw_write_bits((int *) address, 0xff << ((int_ID & 0x3) << 3), value);
42c: e2400b4a sub r0, r0, #75776 ; 0x12800
430: e3a010ff mov r1, #255 ; 0xff
434: e1a01311 lsl r1, r1, r3
438: ebffffea bl 3e8 <hw_write_bits>
* n = (integer_div(in_ID / 32) * 4
* addr_offset = 0x100 + n
* value = enable << (int_ID & 0x1F) */
n = (int_ID >> 5) << 2;
addr_offset = ICDISER + n;
value = 0x1 << (int_ID & 0x1f);
43c: e204301f and r3, r4, #31
440: e3a02001 mov r2, #1
444: e1a02312 lsl r2, r2, r3
/* Set Interrupt Set-Enable Registers (ICDISERn).
* n = (integer_div(in_ID / 32) * 4
* addr_offset = 0x100 + n
* value = enable << (int_ID & 0x1F) */
n = (int_ID >> 5) << 2;
448: e1a002c4 asr r0, r4, #5
44c: e1a00100 lsl r0, r0, #2
addr_offset = ICDISER + n;
450: e2800c01 add r0, r0, #256 ; 0x100
value = 0x1 << (int_ID & 0x1f);
/* Now that we know the register address and value, we need to set the correct bits in
* the GIC register, without changing the other bits */
address = MPCORE_GIC_DIST + addr_offset;
hw_write_bits((int *) address, 0x1 << (int_ID & 0x1f), value);
454: e2400a13 sub r0, r0, #77824 ; 0x13000
458: e1a01002 mov r1, r2
45c: ebffffe1 bl 3e8 <hw_write_bits>
460: e8bd8010 pop {r4, pc}
00000464 <config_GIC>:
/*
* Configure the Generic Interrupt Controller (GIC)
*/
void config_GIC(void)
{
464: e92d4008 push {r3, lr}
int address; // used to calculate register addresses
/* enable some examples of interrupts */
config_interrupt (PS2_IRQ, CPU0);
468: e3a0004f mov r0, #79 ; 0x4f
46c: e3a01001 mov r1, #1
470: ebffffe7 bl 414 <config_interrupt>
// Set Interrupt Priority Mask Register (ICCPMR). Enable interrupts for lowest priority
address = MPCORE_GIC_CPUIF + ICCPMR;
*((int *) address) = 0xFFFF;
474: e3e02a13 mvn r2, #77824 ; 0x13000
478: e30f3fff movw r3, #65535 ; 0xffff
47c: e5023efb str r3, [r2, #-3835] ; 0xfffff105
// Set CPU Interface Control Register (ICCICR). Enable signaling of interrupts
address = MPCORE_GIC_CPUIF + ICCICR;
*((int *) address) = ENABLE;
480: e3a03001 mov r3, #1
484: e5023eff str r3, [r2, #-3839] ; 0xfffff101
// Configure the Distributor Control Register (ICDDCR) to send pending interrupts to CPUs
address = MPCORE_GIC_DIST + ICDDCR;
*((int *) address) = ENABLE;
488: e3e02a12 mvn r2, #73728 ; 0x12000
48c: e5023fff str r3, [r2, #-4095] ; 0xfffff001
490: e8bd8008 pop {r3, pc}
00000494 <plot_pixel>:
// subroutine for plotting text on the screen
void VGA_text(int x, int y, char *text_ptr);
// subroutine for plotting a pixel on the screen
void plot_pixel(int x, int y, short int line_color) {
*(short *) (pixel_buffer_start + (y << 10) + (x << 1)) = line_color;
494: e30f36bc movw r3, #63164 ; 0xf6bc
498: e3403009 movt r3, #9
49c: e593300c ldr r3, [r3, #12]
4a0: e1a00080 lsl r0, r0, #1
4a4: e0831501 add r1, r3, r1, lsl #10
4a8: e18120b0 strh r2, [r1, r0]
4ac: e12fff1e bx lr
000004b0 <VGA_text>:
}
// subroutine for plotting text on the screen
void VGA_text(int x, int y, char *text_ptr) {
/* assume that the text string fits on one line */
int offset = (y << 7) + x;
4b0: e0801381 add r1, r0, r1, lsl #7
while (*(text_ptr)) // while it hasn't reach the null-terminating char in the string
4b4: e5d23000 ldrb r3, [r2]
4b8: e3530000 cmp r3, #0
4bc: 012fff1e bxeq lr
{
// write to the character buffer
*(character_buffer + offset) = *(text_ptr);
4c0: e301ca60 movw r12, #6752 ; 0x1a60
4c4: e340c000 movt r12, #0
4c8: e59c0000 ldr r0, [r12]
4cc: e7c03001 strb r3, [r0, r1]
++text_ptr;
++offset;
4d0: e2811001 add r1, r1, #1
// subroutine for plotting text on the screen
void VGA_text(int x, int y, char *text_ptr) {
/* assume that the text string fits on one line */
int offset = (y << 7) + x;
while (*(text_ptr)) // while it hasn't reach the null-terminating char in the string
4d4: e5f23001 ldrb r3, [r2, #1]!
4d8: e3530000 cmp r3, #0
4dc: 1afffff9 bne 4c8 <VGA_text+0x18>
4e0: e12fff1e bx lr
000004e4 <swap>:
}
// function for swapping two intergers
void swap(int *left, int *right) {
int temp = *left;
4e4: e5903000 ldr r3, [r0]
*left = *right;
4e8: e5912000 ldr r2, [r1]
4ec: e5802000 str r2, [r0]
*right = temp;
4f0: e5813000 str r3, [r1]
4f4: e12fff1e bx lr
000004f8 <plot_line>:
}
// subroutine for plotting a line on the screen (currently not used in this program)
void plot_line(int x0, int y0, int x1, int y1, short int line_color) {
4f8: e92d4ff0 push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
4fc: e24dd014 sub sp, sp, #20
500: e58d000c str r0, [sp, #12]
504: e58d1008 str r1, [sp, #8]
508: e58d2004 str r2, [sp, #4]
50c: e58d3000 str r3, [sp]
510: e1dda3f8 ldrsh r10, [sp, #56] ; 0x38
bool is_steep = abs(y1 - y0) > abs(x1 - x0);
514: e0613003 rsb r3, r1, r3
518: e3530000 cmp r3, #0
51c: b2633000 rsblt r3, r3, #0
520: e0602002 rsb r2, r0, r2
524: e0228fc2 eor r8, r2, r2, asr #31
528: e0488fc2 sub r8, r8, r2, asr #31
52c: e1530008 cmp r3, r8
530: d3a08000 movle r8, #0
534: c3a08001 movgt r8, #1
if (is_steep) {
538: e3580000 cmp r8, #0
53c: 0a000005 beq 558 <plot_line+0x60>
swap(&x0, &y0);
540: e28d000c add r0, sp, #12
544: e28d1008 add r1, sp, #8
548: ebffffe5 bl 4e4 <swap>
swap(&x1, &y1);
54c: e28d0004 add r0, sp, #4
550: e1a0100d mov r1, sp
554: ebffffe2 bl 4e4 <swap>
}
if (x0 > x1) {
558: e59d3004 ldr r3, [sp, #4]
55c: e59d200c ldr r2, [sp, #12]
560: e1520003 cmp r2, r3
564: da000005 ble 580 <plot_line+0x88>
swap(&x0, &x1);
568: e28d000c add r0, sp, #12
56c: e28d1004 add r1, sp, #4
570: ebffffdb bl 4e4 <swap>
swap(&y0, &y1);
574: e28d0008 add r0, sp, #8
578: e1a0100d mov r1, sp
57c: ebffffd8 bl 4e4 <swap>
}
int delta_x = x1 - x0;
580: e59d3004 ldr r3, [sp, #4]
584: e59d500c ldr r5, [sp, #12]
588: e0659003 rsb r9, r5, r3
int delta_y = abs(y1 - y0);
58c: e59d2000 ldr r2, [sp]
590: e59d6008 ldr r6, [sp, #8]
594: e0667002 rsb r7, r6, r2
598: e3570000 cmp r7, #0
59c: b2677000 rsblt r7, r7, #0
int error = -(delta_x / 2);
5a0: e0894fa9 add r4, r9, r9, lsr #31
5a4: e1a040c4 asr r4, r4, #1
5a8: e2644000 rsb r4, r4, #0
int y = y0;
int y_step;
if (y0 < y1) {
y_step = 1;
5ac: e1520006 cmp r2, r6
5b0: d3e0b000 mvnle r11, #0
5b4: c3a0b001 movgt r11, #1
} else {
y_step = -1;
}
for (int x = x0; x <= x1; x++) {
5b8: e1530005 cmp r3, r5
5bc: ba00000d blt 5f8 <plot_line+0x100>
if (is_steep) {
5c0: e3580000 cmp r8, #0
plot_pixel(y, x, line_color);
5c4: 11a00006 movne r0, r6
5c8: 11a01005 movne r1, r5
} else {
plot_pixel(x, y, line_color);
5cc: 01a00005 moveq r0, r5
5d0: 01a01006 moveq r1, r6
5d4: e1a0200a mov r2, r10
5d8: ebffffad bl 494 <plot_pixel>
}
error += delta_y;
if (error >= 0) {
5dc: e0944007 adds r4, r4, r7
y += y_step;
5e0: 5086600b addpl r6, r6, r11
error -= delta_x;
5e4: 50694004 rsbpl r4, r9, r4
y_step = 1;
} else {
y_step = -1;
}
for (int x = x0; x <= x1; x++) {
5e8: e2855001 add r5, r5, #1
5ec: e59d3004 ldr r3, [sp, #4]
5f0: e1530005 cmp r3, r5
5f4: aafffff1 bge 5c0 <plot_line+0xc8>
if (error >= 0) {
y += y_step;
error -= delta_x;
}
}
}
5f8: e28dd014 add sp, sp, #20
5fc: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
00000600 <plot_image>:
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
600: e92d4ff0 push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
604: e24dd01c sub sp, sp, #28
608: e58d000c str r0, [sp, #12]
60c: e58d2010 str r2, [sp, #16]
610: e58d3004 str r3, [sp, #4]
614: e59d3040 ldr r3, [sp, #64] ; 0x40
int i = 0; // index for pixel colours in the image array
for (unsigned y = 0; y < height; y++) {
618: e3530000 cmp r3, #0
61c: 0a00002d beq 6d8 <plot_image+0xd8>
620: e1a06001 mov r6, r1
}
}
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
624: e0833001 add r3, r3, r1
628: e58d3008 str r3, [sp, #8]
int i = 0; // index for pixel colours in the image array
62c: e3a0b000 mov r11, #0
}
}
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
630: e59d2004 ldr r2, [sp, #4]
634: e0828000 add r8, r2, r0
int plotX = initialX + x;
int plotY = initialY + y;
// check for magenta, which is selected as a substitute of the alpha(transparent) colour
// when the pixel is out of bound, ignore it
if (imageArray[i] != 0b1111100000011111 && plotX >= 0 && plotY >= 0 && plotX < 320 && plotY < 240)
638: e30f781f movw r7, #63519 ; 0xf81f
63c: e300913f movw r9, #319 ; 0x13f
}
}
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
640: e2423001 sub r3, r2, #1
644: e58d3014 str r3, [sp, #20]
648: ea000018 b 6b0 <plot_image+0xb0>
int plotX = initialX + x;
int plotY = initialY + y;
// check for magenta, which is selected as a substitute of the alpha(transparent) colour
// when the pixel is out of bound, ignore it
if (imageArray[i] != 0b1111100000011111 && plotX >= 0 && plotY >= 0 && plotX < 320 && plotY < 240)
64c: e5b52004 ldr r2, [r5, #4]!
650: e1520007 cmp r2, r7
654: 0a00000b beq 688 <plot_image+0x88>
int i = 0; // index for pixel colours in the image array
for (unsigned y = 0; y < height; y++) {
for (unsigned x = 0; x < width; x++) {
int plotX = initialX + x;
658: e1a00004 mov r0, r4
int plotY = initialY + y;
65c: e1a01006 mov r1, r6
// check for magenta, which is selected as a substitute of the alpha(transparent) colour
// when the pixel is out of bound, ignore it
if (imageArray[i] != 0b1111100000011111 && plotX >= 0 && plotY >= 0 && plotX < 320 && plotY < 240)
660: e3540000 cmp r4, #0
664: b3a03000 movlt r3, #0
668: a20a3001 andge r3, r10, #1
66c: e3530000 cmp r3, #0
670: 0a000004 beq 688 <plot_image+0x88>
674: e1540009 cmp r4, r9
678: d35600ef cmple r6, #239 ; 0xef
67c: ca000001 bgt 688 <plot_image+0x88>
plot_pixel(plotX, plotY, imageArray[i]);
680: e6bf2072 sxth r2, r2
684: ebffff82 bl 494 <plot_pixel>
688: e2844001 add r4, r4, #1
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
int i = 0; // index for pixel colours in the image array
for (unsigned y = 0; y < height; y++) {
for (unsigned x = 0; x < width; x++) {
68c: e1540008 cmp r4, r8
690: 1affffed bne 64c <plot_image+0x4c>
}
}
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
694: e28bb001 add r11, r11, #1
698: e59d2014 ldr r2, [sp, #20]
69c: e08bb002 add r11, r11, r2
6a0: e2866001 add r6, r6, #1
int i = 0; // index for pixel colours in the image array
for (unsigned y = 0; y < height; y++) {
6a4: e59d3008 ldr r3, [sp, #8]
6a8: e1560003 cmp r6, r3
6ac: 0a000009 beq 6d8 <plot_image+0xd8>
for (unsigned x = 0; x < width; x++) {
6b0: e59d2004 ldr r2, [sp, #4]
6b4: e3520000 cmp r2, #0
6b8: 0afffff8 beq 6a0 <plot_image+0xa0>
}
}
// subroutine for plotting an image given a specific location and image array
void plot_image(int initialX, int initialY, int imageArray[], unsigned width, unsigned height) {
6bc: e24b5001 sub r5, r11, #1
6c0: e59d3010 ldr r3, [sp, #16]
6c4: e0835105 add r5, r3, r5, lsl #2
6c8: e59d400c ldr r4, [sp, #12]
int plotX = initialX + x;
int plotY = initialY + y;
// check for magenta, which is selected as a substitute of the alpha(transparent) colour
// when the pixel is out of bound, ignore it
if (imageArray[i] != 0b1111100000011111 && plotX >= 0 && plotY >= 0 && plotX < 320 && plotY < 240)
6cc: e1e0a006 mvn r10, r6
6d0: e1a0afaa lsr r10, r10, #31
6d4: eaffffdc b 64c <plot_image+0x4c>
plot_pixel(plotX, plotY, imageArray[i]);
i++; // switch to the next pixel colour
}
}
}
6d8: e28dd01c add sp, sp, #28
6dc: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
000006e0 <plot_car_on_road>:
void plot_road(ROAD *myRoad) {
plot_image(0, myRoad->initialY, image_road_320x120, 320, 120);
}
// subroutine for plotting a car's image onto the screen
void plot_car_on_road(ROAD *myRoad) {
6e0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
6e4: e24dd00c sub sp, sp, #12
plot_image(myRoad->carOnRoad.x, myRoad->carOnRoad.y, myRoad->carOnRoad.carImage,
6e8: e590c008 ldr r12, [r0, #8]
6ec: e590100c ldr r1, [r0, #12]
6f0: e5902020 ldr r2, [r0, #32]
6f4: e5903014 ldr r3, [r0, #20]
6f8: e5900018 ldr r0, [r0, #24]
6fc: e58d0000 str r0, [sp]
700: e1a0000c mov r0, r12
704: ebffffbd bl 600 <plot_image>
(unsigned int) myRoad->carOnRoad.imageWidth,
(unsigned int) myRoad->carOnRoad.imageHeight);
}
708: e28dd00c add sp, sp, #12
70c: e8bd8000 ldmfd sp!, {pc}
00000710 <plot_road>:
// subroutine for plotting the chicken on the screen
// will select the correct image according to the chicken's current facing
void plot_chicken(chick *myChick);
// subroutine for plotting a road's image onto the screen
void plot_road(ROAD *myRoad) {
710: e52de004 push {lr} ; (str lr, [sp, #-4]!)
714: e24dd00c sub sp, sp, #12
plot_image(0, myRoad->initialY, image_road_320x120, 320, 120);
718: e5901000 ldr r1, [r0]
71c: e3a03078 mov r3, #120 ; 0x78
720: e58d3000 str r3, [sp]
724: e3a00000 mov r0, #0
728: e59f200c ldr r2, [pc, #12] ; 73c <plot_road+0x2c>
72c: e3a03d05 mov r3, #320 ; 0x140
730: ebffffb2 bl 600 <plot_image>
}
734: e28dd00c add sp, sp, #12
738: e8bd8000 ldmfd sp!, {pc}
73c: 00001a64 .word 0x00001a64
00000740 <clear_screen>:
}
}
}
// subroutine for clearing the whole screen by writing black to every pixel
void clear_screen() {
740: e92d4070 push {r4, r5, r6, lr}
for (int y = 0; y < 240; y++) {
744: e3a05000 mov r5, #0
}
}
}
// subroutine for clearing the whole screen by writing black to every pixel
void clear_screen() {
748: e1a06005 mov r6, r5
74c: ea000009 b 778 <clear_screen+0x38>
for (int y = 0; y < 240; y++) {
for (int x = 0; x < 320; x++) {
plot_pixel(x, y, 0);
750: e1a00004 mov r0, r4
754: e1a01005 mov r1, r5
758: e1a02006 mov r2, r6
75c: ebffff4c bl 494 <plot_pixel>
}
// subroutine for clearing the whole screen by writing black to every pixel
void clear_screen() {
for (int y = 0; y < 240; y++) {
for (int x = 0; x < 320; x++) {
760: e2844001 add r4, r4, #1
764: e3540d05 cmp r4, #320 ; 0x140
768: 1afffff8 bne 750 <clear_screen+0x10>
}
}
// subroutine for clearing the whole screen by writing black to every pixel
void clear_screen() {
for (int y = 0; y < 240; y++) {
76c: e2855001 add r5, r5, #1
770: e35500f0 cmp r5, #240 ; 0xf0
774: 08bd8070 popeq {r4, r5, r6, pc}
}
}
}
// subroutine for clearing the whole screen by writing black to every pixel
void clear_screen() {
778: e1a04006 mov r4, r6
77c: eafffff3 b 750 <clear_screen+0x10>
00000780 <wait_for_vsync>:
bool wait_for_vsync() {
// register for storing the plotting status
register int status;
// write to switch the front&back VGA buffer
*pixel_ctrl_ptr = 1;
780: e30739c8 movw r3, #31176 ; 0x79c8
784: e3403002 movt r3, #2
788: e5132764 ldr r2, [r3, #-1892] ; 0xfffff89c
78c: e3a01001 mov r1, #1
790: e5821000 str r1, [r2]
// keep getting the plotting status until the plotting is finished
// which is denoted by status "1"
status = *(pixel_ctrl_ptr + 3);
794: e5132764 ldr r2, [r3, #-1892] ; 0xfffff89c
798: e592300c ldr r3, [r2, #12]
while ((status & 0x01) != 0) {
79c: e3130001 tst r3, #1
7a0: 0a000002 beq 7b0 <wait_for_vsync+0x30>
status = *(pixel_ctrl_ptr + 3);
7a4: e592300c ldr r3, [r2, #12]
*pixel_ctrl_ptr = 1;
// keep getting the plotting status until the plotting is finished
// which is denoted by status "1"
status = *(pixel_ctrl_ptr + 3);
while ((status & 0x01) != 0) {
7a8: e3130001 tst r3, #1
7ac: 1afffffc bne 7a4 <wait_for_vsync+0x24>
status = *(pixel_ctrl_ptr + 3);
}
return true;
}
7b0: e3a00001 mov r0, #1
7b4: e12fff1e bx lr
000007b8 <plot_chicken>:
// subroutine for plotting the chicken on the screen
// will select the correct image according to the chicken's current facing
void plot_chicken(chick *myChick) {
7b8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
7bc: e24dd00c sub sp, sp, #12
7c0: e1a02000 mov r2, r0
// properties of the chicken facing image
unsigned height = 0;
unsigned width = 0;
// get the face type from the chicken
switch (myChick->faceType) {
7c4: e590c008 ldr r12, [r0, #8]
7c8: e35c0003 cmp r12, #3
7cc: 979ff10c ldrls pc, [pc, r12, lsl #2]
7d0: ea000003 b 7e4 <plot_chicken+0x2c>
7d4: 00000808 .word 0x00000808