-
Notifications
You must be signed in to change notification settings - Fork 0
/
SimpleExample328.asm
2871 lines (2718 loc) · 96.4 KB
/
SimpleExample328.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
/tmp/build5736274865649334927.tmp/SimpleExample328.cpp.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 59 00 jmp 0xb2 ; 0xb2 <__ctors_end>
4: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
8: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
c: 0c 94 91 01 jmp 0x322 ; 0x322 <__vector_3>
10: 0c 94 be 01 jmp 0x37c ; 0x37c <__vector_4>
14: 0c 94 eb 01 jmp 0x3d6 ; 0x3d6 <__vector_5>
18: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
1c: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
20: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
24: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
28: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
2c: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
30: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
34: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
38: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
3c: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
40: 0c 94 9f 02 jmp 0x53e ; 0x53e <__vector_16>
44: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
48: 0c 94 3e 04 jmp 0x87c ; 0x87c <__vector_18>
4c: 0c 94 81 04 jmp 0x902 ; 0x902 <__vector_19>
50: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
54: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
58: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
5c: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
60: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
64: 0c 94 81 00 jmp 0x102 ; 0x102 <__bad_interrupt>
00000068 <digital_pin_to_bit_mask_PGM>:
68: 01 02 04 08 10 20 40 80 01 02 04 08 10 20 01 02 ..... @...... ..
78: 04 08 10 20 ...
0000007c <digital_pin_to_port_PGM>:
7c: 04 04 04 04 04 04 04 04 02 02 02 02 02 02 03 03 ................
8c: 03 03 03 03 ....
00000090 <port_to_input_PGM>:
90: 00 00 00 00 23 00 26 00 29 00 ....#.&.).
0000009a <port_to_output_PGM>:
9a: 00 00 00 00 25 00 28 00 2b 00 ....%.(.+.
000000a4 <port_to_mode_PGM>:
a4: 00 00 00 00 24 00 27 00 2a 00 ....$.'.*.
000000ae <__ctors_start>:
ae: 53 02 muls r21, r19
b0: 3d 05 cpc r19, r13
000000b2 <__ctors_end>:
b2: 11 24 eor r1, r1
b4: 1f be out 0x3f, r1 ; 63
b6: cf ef ldi r28, 0xFF ; 255
b8: d8 e0 ldi r29, 0x08 ; 8
ba: de bf out 0x3e, r29 ; 62
bc: cd bf out 0x3d, r28 ; 61
000000be <__do_copy_data>:
be: 11 e0 ldi r17, 0x01 ; 1
c0: a0 e0 ldi r26, 0x00 ; 0
c2: b1 e0 ldi r27, 0x01 ; 1
c4: ee e5 ldi r30, 0x5E ; 94
c6: f0 e1 ldi r31, 0x10 ; 16
c8: 02 c0 rjmp .+4 ; 0xce <__do_copy_data+0x10>
ca: 05 90 lpm r0, Z+
cc: 0d 92 st X+, r0
ce: aa 36 cpi r26, 0x6A ; 106
d0: b1 07 cpc r27, r17
d2: d9 f7 brne .-10 ; 0xca <__do_copy_data+0xc>
000000d4 <__do_clear_bss>:
d4: 12 e0 ldi r17, 0x02 ; 2
d6: aa e6 ldi r26, 0x6A ; 106
d8: b1 e0 ldi r27, 0x01 ; 1
da: 01 c0 rjmp .+2 ; 0xde <.do_clear_bss_start>
000000dc <.do_clear_bss_loop>:
dc: 1d 92 st X+, r1
000000de <.do_clear_bss_start>:
de: a3 34 cpi r26, 0x43 ; 67
e0: b1 07 cpc r27, r17
e2: e1 f7 brne .-8 ; 0xdc <.do_clear_bss_loop>
000000e4 <__do_global_ctors>:
e4: 10 e0 ldi r17, 0x00 ; 0
e6: c2 eb ldi r28, 0xB2 ; 178
e8: d0 e0 ldi r29, 0x00 ; 0
ea: 04 c0 rjmp .+8 ; 0xf4 <__do_global_ctors+0x10>
ec: 22 97 sbiw r28, 0x02 ; 2
ee: fe 01 movw r30, r28
f0: 0e 94 29 08 call 0x1052 ; 0x1052 <__tablejump__>
f4: ce 3a cpi r28, 0xAE ; 174
f6: d1 07 cpc r29, r17
f8: c9 f7 brne .-14 ; 0xec <__do_global_ctors+0x8>
fa: 0e 94 cf 06 call 0xd9e ; 0xd9e <main>
fe: 0c 94 2d 08 jmp 0x105a ; 0x105a <_exit>
00000102 <__bad_interrupt>:
102: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
00000106 <_Z17interruptFunctionv>:
106: 80 91 6a 01 lds r24, 0x016A
10a: 8f 5f subi r24, 0xFF ; 255
10c: 80 93 6a 01 sts 0x016A, r24
110: 08 95 ret
00000112 <_ZN9PCintPort6enableEPNS_8PCintPinEPFvvEh>:
return port;
}
void PCintPort::enable(PCintPin* p, PCIntvoidFuncPtr userFunc, uint8_t mode) {
112: cf 93 push r28
114: df 93 push r29
116: dc 01 movw r26, r24
118: fb 01 movw r30, r22
// Enable the pin for interrupts by adding to the PCMSKx register.
// ...The final steps; at this point the interrupt is enabled on this pin.
p->mode=mode;
11a: 22 83 std Z+2, r18 ; 0x02
p->PCintFunc=userFunc;
11c: 51 83 std Z+1, r21 ; 0x01
11e: 40 83 st Z, r20
}
else {
portPCMask |= p->mask;
}
#else
portPCMask |= p->mask;
120: 12 96 adiw r26, 0x02 ; 2
122: cd 91 ld r28, X+
124: dc 91 ld r29, X
126: 13 97 sbiw r26, 0x03 ; 3
128: 88 81 ld r24, Y
12a: 93 81 ldd r25, Z+3 ; 0x03
12c: 89 2b or r24, r25
12e: 88 83 st Y, r24
#endif
if ((p->mode == RISING) || (p->mode == CHANGE)) portRisingPins |= p->mask;
130: 82 81 ldd r24, Z+2 ; 0x02
132: 8d 7f andi r24, 0xFD ; 253
134: 81 30 cpi r24, 0x01 ; 1
136: 41 f4 brne .+16 ; 0x148 <_ZN9PCintPort6enableEPNS_8PCintPinEPFvvEh+0x36>
138: 15 96 adiw r26, 0x05 ; 5
13a: 8c 91 ld r24, X
13c: 15 97 sbiw r26, 0x05 ; 5
13e: 93 81 ldd r25, Z+3 ; 0x03
140: 89 2b or r24, r25
142: 15 96 adiw r26, 0x05 ; 5
144: 8c 93 st X, r24
146: 15 97 sbiw r26, 0x05 ; 5
if ((p->mode == FALLING) || (p->mode == CHANGE)) portFallingPins |= p->mask;
148: 82 81 ldd r24, Z+2 ; 0x02
14a: 81 50 subi r24, 0x01 ; 1
14c: 82 30 cpi r24, 0x02 ; 2
14e: 40 f4 brcc .+16 ; 0x160 <_ZN9PCintPort6enableEPNS_8PCintPinEPFvvEh+0x4e>
150: 16 96 adiw r26, 0x06 ; 6
152: 8c 91 ld r24, X
154: 16 97 sbiw r26, 0x06 ; 6
156: 93 81 ldd r25, Z+3 ; 0x03
158: 89 2b or r24, r25
15a: 16 96 adiw r26, 0x06 ; 6
15c: 8c 93 st X, r24
15e: 16 97 sbiw r26, 0x06 ; 6
PCICR |= PCICRbit;
160: 80 91 68 00 lds r24, 0x0068
164: 14 96 adiw r26, 0x04 ; 4
166: 9c 91 ld r25, X
168: 89 2b or r24, r25
16a: 80 93 68 00 sts 0x0068, r24
}
16e: df 91 pop r29
170: cf 91 pop r28
172: 08 95 ret
00000174 <_ZN9PCintPort6addPinEhPFvvEh>:
int8_t PCintPort::addPin(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, uint8_t mode)
{
174: ef 92 push r14
176: ff 92 push r15
178: 0f 93 push r16
17a: 1f 93 push r17
17c: cf 93 push r28
17e: df 93 push r29
180: 00 d0 rcall .+0 ; 0x182 <_ZN9PCintPort6addPinEhPFvvEh+0xe>
182: 00 d0 rcall .+0 ; 0x184 <_ZN9PCintPort6addPinEhPFvvEh+0x10>
184: cd b7 in r28, 0x3d ; 61
186: de b7 in r29, 0x3e ; 62
188: 8c 01 movw r16, r24
PCintPin* tmp;
tmp=firstPin;
18a: fc 01 movw r30, r24
18c: e0 84 ldd r14, Z+8 ; 0x08
18e: f1 84 ldd r15, Z+9 ; 0x09
// Add to linked list, starting with firstPin. If pin already exists, just enable.
if (firstPin != NULL) {
190: e1 14 cp r14, r1
192: f1 04 cpc r15, r1
194: 89 f0 breq .+34 ; 0x1b8 <_ZN9PCintPort6addPinEhPFvvEh+0x44>
do {
if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); }
196: f7 01 movw r30, r14
198: 84 81 ldd r24, Z+4 ; 0x04
19a: 86 13 cpse r24, r22
19c: 06 c0 rjmp .+12 ; 0x1aa <_ZN9PCintPort6addPinEhPFvvEh+0x36>
19e: b7 01 movw r22, r14
1a0: c8 01 movw r24, r16
1a2: 0e 94 89 00 call 0x112 ; 0x112 <_ZN9PCintPort6enableEPNS_8PCintPinEPFvvEh>
1a6: 80 e0 ldi r24, 0x00 ; 0
1a8: 40 c0 rjmp .+128 ; 0x22a <_ZN9PCintPort6addPinEhPFvvEh+0xb6>
if (tmp->next == NULL) break;
1aa: f7 01 movw r30, r14
1ac: 85 81 ldd r24, Z+5 ; 0x05
1ae: 96 81 ldd r25, Z+6 ; 0x06
1b0: 00 97 sbiw r24, 0x00 ; 0
1b2: 11 f0 breq .+4 ; 0x1b8 <_ZN9PCintPort6addPinEhPFvvEh+0x44>
tmp=tmp->next;
1b4: 7c 01 movw r14, r24
1b6: ef cf rjmp .-34 ; 0x196 <_ZN9PCintPort6addPinEhPFvvEh+0x22>
} while (true);
}
// Create pin p: fill in the data.
PCintPin* p=new PCintPin;
1b8: 87 e0 ldi r24, 0x07 ; 7
1ba: 90 e0 ldi r25, 0x00 ; 0
1bc: 2c 83 std Y+4, r18 ; 0x04
1be: 4a 83 std Y+2, r20 ; 0x02
1c0: 5b 83 std Y+3, r21 ; 0x03
1c2: 69 83 std Y+1, r22 ; 0x01
1c4: 0e 94 dc 06 call 0xdb8 ; 0xdb8 <_Znwj>
1c8: dc 01 movw r26, r24
protected:
class PCintPin {
public:
PCintPin() :
PCintFunc((PCIntvoidFuncPtr)NULL),
mode(0) {}
1ca: 11 96 adiw r26, 0x01 ; 1
1cc: 1c 92 st X, r1
1ce: 1e 92 st -X, r1
1d0: 12 96 adiw r26, 0x02 ; 2
1d2: 1c 92 st X, r1
1d4: 12 97 sbiw r26, 0x02 ; 2
} while (true);
}
// Create pin p: fill in the data.
PCintPin* p=new PCintPin;
if (p == NULL) return(-1);
1d6: 2c 81 ldd r18, Y+4 ; 0x04
1d8: 4a 81 ldd r20, Y+2 ; 0x02
1da: 5b 81 ldd r21, Y+3 ; 0x03
1dc: 69 81 ldd r22, Y+1 ; 0x01
1de: 00 97 sbiw r24, 0x00 ; 0
1e0: 19 f1 breq .+70 ; 0x228 <_ZN9PCintPort6addPinEhPFvvEh+0xb4>
p->arduinoPin=arduinoPin;
1e2: 14 96 adiw r26, 0x04 ; 4
1e4: 6c 93 st X, r22
1e6: 14 97 sbiw r26, 0x04 ; 4
p->mode = mode;
1e8: 12 96 adiw r26, 0x02 ; 2
1ea: 2c 93 st X, r18
1ec: 12 97 sbiw r26, 0x02 ; 2
p->next=NULL;
1ee: 16 96 adiw r26, 0x06 ; 6
1f0: 1c 92 st X, r1
1f2: 1e 92 st -X, r1
1f4: 15 97 sbiw r26, 0x05 ; 5
p->mask = digitalPinToBitMask(arduinoPin); // the mask
1f6: e6 2f mov r30, r22
1f8: f0 e0 ldi r31, 0x00 ; 0
1fa: e8 59 subi r30, 0x98 ; 152
1fc: ff 4f sbci r31, 0xFF ; 255
1fe: e4 91 lpm r30, Z
200: 13 96 adiw r26, 0x03 ; 3
202: ec 93 st X, r30
204: 13 97 sbiw r26, 0x03 ; 3
if (firstPin == NULL) firstPin=p;
206: f8 01 movw r30, r16
208: 80 85 ldd r24, Z+8 ; 0x08
20a: 91 85 ldd r25, Z+9 ; 0x09
20c: 89 2b or r24, r25
20e: 19 f4 brne .+6 ; 0x216 <_ZN9PCintPort6addPinEhPFvvEh+0xa2>
210: b1 87 std Z+9, r27 ; 0x09
212: a0 87 std Z+8, r26 ; 0x08
214: 03 c0 rjmp .+6 ; 0x21c <_ZN9PCintPort6addPinEhPFvvEh+0xa8>
else tmp->next=p; // NOTE that tmp cannot be NULL.
216: f7 01 movw r30, r14
218: b6 83 std Z+6, r27 ; 0x06
21a: a5 83 std Z+5, r26 ; 0x05
int addr = (int) p;
Serial.print(" instance addr: "); Serial.println(addr, HEX);
Serial.print("userFunc addr: "); Serial.println((int)p->PCintFunc, HEX);
#endif
enable(p, userFunc, mode);
21c: bd 01 movw r22, r26
21e: c8 01 movw r24, r16
220: 0e 94 89 00 call 0x112 ; 0x112 <_ZN9PCintPort6enableEPNS_8PCintPinEPFvvEh>
#ifdef DEBUG
Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC), Serial.print (" pin stored: ");
int addr = (int) p;
Serial.print(" instance addr: "); Serial.println(addr, HEX);
#endif
return(1);
224: 81 e0 ldi r24, 0x01 ; 1
226: 01 c0 rjmp .+2 ; 0x22a <_ZN9PCintPort6addPinEhPFvvEh+0xb6>
} while (true);
}
// Create pin p: fill in the data.
PCintPin* p=new PCintPin;
if (p == NULL) return(-1);
228: 8f ef ldi r24, 0xFF ; 255
Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC), Serial.print (" pin stored: ");
int addr = (int) p;
Serial.print(" instance addr: "); Serial.println(addr, HEX);
#endif
return(1);
}
22a: 0f 90 pop r0
22c: 0f 90 pop r0
22e: 0f 90 pop r0
230: 0f 90 pop r0
232: df 91 pop r29
234: cf 91 pop r28
236: 1f 91 pop r17
238: 0f 91 pop r16
23a: ff 90 pop r15
23c: ef 90 pop r14
23e: 08 95 ret
00000240 <_ZN9PCintPort15attachInterruptEhPFvvEi>:
/*
* attach an interrupt to a specific pin using pin change interrupts.
*/
int8_t PCintPort::attachInterrupt(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, int mode)
{
240: 24 2f mov r18, r20
PCintPort *port;
uint8_t portNum = digitalPinToPort(arduinoPin);
242: e8 2f mov r30, r24
244: f0 e0 ldi r31, 0x00 ; 0
246: e4 58 subi r30, 0x84 ; 132
248: ff 4f sbci r31, 0xFF ; 255
24a: e4 91 lpm r30, Z
if ((portNum == NOT_A_PORT) || (userFunc == NULL)) return(-1);
24c: ee 23 and r30, r30
24e: d9 f0 breq .+54 ; 0x286 <_ZN9PCintPort15attachInterruptEhPFvvEi+0x46>
250: 61 15 cp r22, r1
252: 71 05 cpc r23, r1
254: c1 f0 breq .+48 ; 0x286 <_ZN9PCintPort15attachInterruptEhPFvvEi+0x46>
#endif // USE_PORT_JK
static PCintPort *lookupPortNumToPort( int portNum ) {
PCintPort *port = NULL;
switch (portNum) {
256: f0 e0 ldi r31, 0x00 ; 0
258: 32 97 sbiw r30, 0x02 ; 2
25a: e3 30 cpi r30, 0x03 ; 3
25c: f1 05 cpc r31, r1
25e: 40 f4 brcc .+16 ; 0x270 <_ZN9PCintPort15attachInterruptEhPFvvEi+0x30>
260: ee 0f add r30, r30
262: ff 1f adc r31, r31
264: ed 5a subi r30, 0xAD ; 173
266: fe 4f sbci r31, 0xFE ; 254
268: 01 90 ld r0, Z+
26a: f0 81 ld r31, Z
26c: e0 2d mov r30, r0
26e: 02 c0 rjmp .+4 ; 0x274 <_ZN9PCintPort15attachInterruptEhPFvvEi+0x34>
270: e0 e0 ldi r30, 0x00 ; 0
272: f0 e0 ldi r31, 0x00 ; 0
if ((portNum == NOT_A_PORT) || (userFunc == NULL)) return(-1);
port=lookupPortNumToPort(portNum);
// Added by GreyGnome... must set the initial value of lastPinView for it to be correct on the 1st interrupt.
// ...but even then, how do you define "correct"? Ultimately, the user must specify (not provisioned for yet).
port->lastPinView=port->portInputReg;
274: a0 81 ld r26, Z
276: b1 81 ldd r27, Z+1 ; 0x01
278: 9c 91 ld r25, X
27a: 97 83 std Z+7, r25 ; 0x07
#ifdef DEBUG
Serial.print("attachInterrupt- pin: "); Serial.println(arduinoPin, DEC);
#endif
// map pin to PCIR register
return(port->addPin(arduinoPin,userFunc,mode));
27c: ab 01 movw r20, r22
27e: 68 2f mov r22, r24
280: cf 01 movw r24, r30
282: 0c 94 ba 00 jmp 0x174 ; 0x174 <_ZN9PCintPort6addPinEhPFvvEh>
}
286: 8f ef ldi r24, 0xFF ; 255
288: 08 95 ret
0000028a <_ZN9PCintPort5PCintEv>:
}
}
// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
void PCintPort::PCint() {
28a: ff 92 push r15
28c: 0f 93 push r16
28e: 1f 93 push r17
290: cf 93 push r28
292: df 93 push r29
294: ec 01 movw r28, r24
PCintPort::s_lastPinView=lastPinView;
intrCount++;
PCintPort::s_count=intrCount;
#endif
uint8_t changedPins = (PCintPort::curr ^ lastPinView) &
((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr ));
296: 20 91 8b 01 lds r18, 0x018B
29a: 8f 81 ldd r24, Y+7 ; 0x07
29c: 3d 81 ldd r19, Y+5 ; 0x05
29e: 90 91 8b 01 lds r25, 0x018B
2a2: 4e 81 ldd r20, Y+6 ; 0x06
2a4: f0 90 8b 01 lds r15, 0x018B
2a8: f0 94 com r15
2aa: f4 22 and r15, r20
2ac: 93 23 and r25, r19
2ae: f9 2a or r15, r25
2b0: 82 27 eor r24, r18
2b2: f8 22 and r15, r24
#ifdef PINMODE
PCintPort::s_currXORlastPinView=PCintPort::curr ^ lastPinView;
PCintPort::s_portRisingPins_nCurr=portRisingPins & PCintPort::curr;
PCintPort::s_portFallingPins_nNCurr=portFallingPins & ~PCintPort::curr;
#endif
lastPinView = PCintPort::curr;
2b4: 80 91 8b 01 lds r24, 0x018B
2b8: 8f 83 std Y+7, r24 ; 0x07
PCintPin* p = firstPin;
2ba: 08 85 ldd r16, Y+8 ; 0x08
2bc: 19 85 ldd r17, Y+9 ; 0x09
while (p) {
2be: 01 15 cp r16, r1
2c0: 11 05 cpc r17, r1
2c2: e1 f0 breq .+56 ; 0x2fc <_ZN9PCintPort5PCintEv+0x72>
// Trigger interrupt if the bit is high and it's set to trigger on mode RISING or CHANGE
// Trigger interrupt if the bit is low and it's set to trigger on mode FALLING or CHANGE
if (p->mask & changedPins) {
2c4: d8 01 movw r26, r16
2c6: 13 96 adiw r26, 0x03 ; 3
2c8: 9c 91 ld r25, X
2ca: 8f 2d mov r24, r15
2cc: 89 23 and r24, r25
2ce: 81 f0 breq .+32 ; 0x2f0 <_ZN9PCintPort5PCintEv+0x66>
#ifndef NO_PIN_STATE
PCintPort::pinState=PCintPort::curr & p->mask ? HIGH : LOW;
2d0: 80 91 8b 01 lds r24, 0x018B
2d4: 89 23 and r24, r25
2d6: 91 e0 ldi r25, 0x01 ; 1
2d8: 09 f4 brne .+2 ; 0x2dc <_ZN9PCintPort5PCintEv+0x52>
2da: 90 e0 ldi r25, 0x00 ; 0
2dc: 90 93 89 01 sts 0x0189, r25
#endif
#ifndef NO_PIN_NUMBER
PCintPort::arduinoPin=p->arduinoPin;
2e0: f8 01 movw r30, r16
2e2: 84 81 ldd r24, Z+4 ; 0x04
2e4: 80 93 8a 01 sts 0x018A, r24
PCintPort::s_portRisingPins=portRisingPins;
PCintPort::s_portFallingPins=portFallingPins;
PCintPort::s_pmask=p->mask;
PCintPort::s_changedPins=changedPins;
#endif
p->PCintFunc();
2e8: 01 90 ld r0, Z+
2ea: f0 81 ld r31, Z
2ec: e0 2d mov r30, r0
2ee: 09 95 icall
}
p=p->next;
2f0: d8 01 movw r26, r16
2f2: 15 96 adiw r26, 0x05 ; 5
2f4: 0d 91 ld r16, X+
2f6: 1c 91 ld r17, X
2f8: 16 97 sbiw r26, 0x06 ; 6
2fa: e1 cf rjmp .-62 ; 0x2be <_ZN9PCintPort5PCintEv+0x34>
}
#ifndef DISABLE_PCINT_MULTI_SERVICE
pcifr = PCIFR & PCICRbit;
2fc: 8b b3 in r24, 0x1b ; 27
2fe: 9c 81 ldd r25, Y+4 ; 0x04
300: 89 23 and r24, r25
if (pcifr == 0) break;
302: 49 f0 breq .+18 ; 0x316 <_ZN9PCintPort5PCintEv+0x8c>
PCIFR |= PCICRbit;
304: 8b b3 in r24, 0x1b ; 27
306: 89 2b or r24, r25
308: 8b bb out 0x1b, r24 ; 27
#ifdef PINMODE
PCintPort::pcint_multi++;
if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; // PCIFR & PCICRbit should ALWAYS be 0 here!
#endif
PCintPort::curr=portInputReg;
30a: e8 81 ld r30, Y
30c: f9 81 ldd r31, Y+1 ; 0x01
30e: 80 81 ld r24, Z
310: 80 93 8b 01 sts 0x018B, r24
}
314: c0 cf rjmp .-128 ; 0x296 <_ZN9PCintPort5PCintEv+0xc>
#endif
}
316: df 91 pop r29
318: cf 91 pop r28
31a: 1f 91 pop r17
31c: 0f 91 pop r16
31e: ff 90 pop r15
320: 08 95 ret
00000322 <__vector_3>:
#define PORTCVECT PCINT1_vect
#define PORTDVECT PCINT2_vect
#endif
#ifndef NO_PORTB_PINCHANGES
ISR(PORTBVECT) {
322: 1f 92 push r1
324: 0f 92 push r0
326: 0f b6 in r0, 0x3f ; 63
328: 0f 92 push r0
32a: 11 24 eor r1, r1
32c: 2f 93 push r18
32e: 3f 93 push r19
330: 4f 93 push r20
332: 5f 93 push r21
334: 6f 93 push r22
336: 7f 93 push r23
338: 8f 93 push r24
33a: 9f 93 push r25
33c: af 93 push r26
33e: bf 93 push r27
340: ef 93 push r30
342: ff 93 push r31
#ifdef PINMODE
PCintPort::s_PORT='B';
#endif
PCintPort::curr = portB.portInputReg;
344: e0 91 7f 01 lds r30, 0x017F
348: f0 91 80 01 lds r31, 0x0180
34c: 80 81 ld r24, Z
34e: 80 93 8b 01 sts 0x018B, r24
portB.PCint();
352: 8f e7 ldi r24, 0x7F ; 127
354: 91 e0 ldi r25, 0x01 ; 1
356: 0e 94 45 01 call 0x28a ; 0x28a <_ZN9PCintPort5PCintEv>
}
35a: ff 91 pop r31
35c: ef 91 pop r30
35e: bf 91 pop r27
360: af 91 pop r26
362: 9f 91 pop r25
364: 8f 91 pop r24
366: 7f 91 pop r23
368: 6f 91 pop r22
36a: 5f 91 pop r21
36c: 4f 91 pop r20
36e: 3f 91 pop r19
370: 2f 91 pop r18
372: 0f 90 pop r0
374: 0f be out 0x3f, r0 ; 63
376: 0f 90 pop r0
378: 1f 90 pop r1
37a: 18 95 reti
0000037c <__vector_4>:
#endif
#ifndef NO_PORTC_PINCHANGES
ISR(PORTCVECT) {
37c: 1f 92 push r1
37e: 0f 92 push r0
380: 0f b6 in r0, 0x3f ; 63
382: 0f 92 push r0
384: 11 24 eor r1, r1
386: 2f 93 push r18
388: 3f 93 push r19
38a: 4f 93 push r20
38c: 5f 93 push r21
38e: 6f 93 push r22
390: 7f 93 push r23
392: 8f 93 push r24
394: 9f 93 push r25
396: af 93 push r26
398: bf 93 push r27
39a: ef 93 push r30
39c: ff 93 push r31
#ifdef PINMODE
PCintPort::s_PORT='C';
#endif
PCintPort::curr = portC.portInputReg;
39e: e0 91 75 01 lds r30, 0x0175
3a2: f0 91 76 01 lds r31, 0x0176
3a6: 80 81 ld r24, Z
3a8: 80 93 8b 01 sts 0x018B, r24
portC.PCint();
3ac: 85 e7 ldi r24, 0x75 ; 117
3ae: 91 e0 ldi r25, 0x01 ; 1
3b0: 0e 94 45 01 call 0x28a ; 0x28a <_ZN9PCintPort5PCintEv>
}
3b4: ff 91 pop r31
3b6: ef 91 pop r30
3b8: bf 91 pop r27
3ba: af 91 pop r26
3bc: 9f 91 pop r25
3be: 8f 91 pop r24
3c0: 7f 91 pop r23
3c2: 6f 91 pop r22
3c4: 5f 91 pop r21
3c6: 4f 91 pop r20
3c8: 3f 91 pop r19
3ca: 2f 91 pop r18
3cc: 0f 90 pop r0
3ce: 0f be out 0x3f, r0 ; 63
3d0: 0f 90 pop r0
3d2: 1f 90 pop r1
3d4: 18 95 reti
000003d6 <__vector_5>:
#endif
#ifndef NO_PORTD_PINCHANGES
ISR(PORTDVECT){
3d6: 1f 92 push r1
3d8: 0f 92 push r0
3da: 0f b6 in r0, 0x3f ; 63
3dc: 0f 92 push r0
3de: 11 24 eor r1, r1
3e0: 2f 93 push r18
3e2: 3f 93 push r19
3e4: 4f 93 push r20
3e6: 5f 93 push r21
3e8: 6f 93 push r22
3ea: 7f 93 push r23
3ec: 8f 93 push r24
3ee: 9f 93 push r25
3f0: af 93 push r26
3f2: bf 93 push r27
3f4: ef 93 push r30
3f6: ff 93 push r31
#ifdef PINMODE
PCintPort::s_PORT='D';
#endif
PCintPort::curr = portD.portInputReg;
3f8: e0 91 6b 01 lds r30, 0x016B
3fc: f0 91 6c 01 lds r31, 0x016C
400: 80 81 ld r24, Z
402: 80 93 8b 01 sts 0x018B, r24
portD.PCint();
406: 8b e6 ldi r24, 0x6B ; 107
408: 91 e0 ldi r25, 0x01 ; 1
40a: 0e 94 45 01 call 0x28a ; 0x28a <_ZN9PCintPort5PCintEv>
}
40e: ff 91 pop r31
410: ef 91 pop r30
412: bf 91 pop r27
414: af 91 pop r26
416: 9f 91 pop r25
418: 8f 91 pop r24
41a: 7f 91 pop r23
41c: 6f 91 pop r22
41e: 5f 91 pop r21
420: 4f 91 pop r20
422: 3f 91 pop r19
424: 2f 91 pop r18
426: 0f 90 pop r0
428: 0f be out 0x3f, r0 ; 63
42a: 0f 90 pop r0
42c: 1f 90 pop r1
42e: 18 95 reti
00000430 <setup>:
430: 62 e0 ldi r22, 0x02 ; 2
432: 82 e1 ldi r24, 0x12 ; 18
434: 0e 94 6d 03 call 0x6da ; 0x6da <pinMode>
438: 42 e0 ldi r20, 0x02 ; 2
43a: 50 e0 ldi r21, 0x00 ; 0
43c: 63 e8 ldi r22, 0x83 ; 131
43e: 70 e0 ldi r23, 0x00 ; 0
440: 82 e1 ldi r24, 0x12 ; 18
442: 0e 94 20 01 call 0x240 ; 0x240 <_ZN9PCintPort15attachInterruptEhPFvvEi>
446: 40 e0 ldi r20, 0x00 ; 0
448: 52 ec ldi r21, 0xC2 ; 194
44a: 61 e0 ldi r22, 0x01 ; 1
44c: 70 e0 ldi r23, 0x00 ; 0
44e: 85 e9 ldi r24, 0x95 ; 149
450: 91 e0 ldi r25, 0x01 ; 1
452: 0e 94 bc 04 call 0x978 ; 0x978 <_ZN14HardwareSerial5beginEm>
456: 66 e0 ldi r22, 0x06 ; 6
458: 71 e0 ldi r23, 0x01 ; 1
45a: 85 e9 ldi r24, 0x95 ; 149
45c: 91 e0 ldi r25, 0x01 ; 1
45e: 0c 94 ee 05 jmp 0xbdc ; 0xbdc <_ZN5Print7printlnEPKc>
00000462 <loop>:
462: 4a e0 ldi r20, 0x0A ; 10
464: 50 e0 ldi r21, 0x00 ; 0
466: 69 e6 ldi r22, 0x69 ; 105
468: 70 e0 ldi r23, 0x00 ; 0
46a: 85 e9 ldi r24, 0x95 ; 149
46c: 91 e0 ldi r25, 0x01 ; 1
46e: 0e 94 a3 06 call 0xd46 ; 0xd46 <_ZN5Print7printlnEii>
472: 68 ee ldi r22, 0xE8 ; 232
474: 73 e0 ldi r23, 0x03 ; 3
476: 80 e0 ldi r24, 0x00 ; 0
478: 90 e0 ldi r25, 0x00 ; 0
47a: 0e 94 0c 03 call 0x618 ; 0x618 <delay>
47e: 6e e2 ldi r22, 0x2E ; 46
480: 71 e0 ldi r23, 0x01 ; 1
482: 85 e9 ldi r24, 0x95 ; 149
484: 91 e0 ldi r25, 0x01 ; 1
486: 0e 94 d1 05 call 0xba2 ; 0xba2 <_ZN5Print5printEPKc>
48a: 60 91 6a 01 lds r22, 0x016A
48e: 4a e0 ldi r20, 0x0A ; 10
490: 50 e0 ldi r21, 0x00 ; 0
492: 85 e9 ldi r24, 0x95 ; 149
494: 91 e0 ldi r25, 0x01 ; 1
496: 0e 94 c8 06 call 0xd90 ; 0xd90 <_ZN5Print5printEhi>
49a: 64 e4 ldi r22, 0x44 ; 68
49c: 71 e0 ldi r23, 0x01 ; 1
49e: 85 e9 ldi r24, 0x95 ; 149
4a0: 91 e0 ldi r25, 0x01 ; 1
4a2: 0c 94 ee 05 jmp 0xbdc ; 0xbdc <_ZN5Print7printlnEPKc>
000004a6 <_GLOBAL__sub_I__ZN9PCintPort4currE>:
// portB=PCintPort(2, 1,PCMSK1);
// index: portInputReg(*portInputRegister(index)),
// pcindex: PCICRbit(1 << pcindex)
// maskReg: portPCMask(maskReg)
PCintPort(int index,int pcindex, volatile uint8_t& maskReg) :
portInputReg(*portInputRegister(index)),
4a6: e4 e9 ldi r30, 0x94 ; 148
4a8: f0 e0 ldi r31, 0x00 ; 0
4aa: 85 91 lpm r24, Z+
4ac: 94 91 lpm r25, Z
portPCMask(maskReg),
PCICRbit(1 << pcindex),
portRisingPins(0),
portFallingPins(0),
firstPin(NULL)
4ae: 90 93 80 01 sts 0x0180, r25
4b2: 80 93 7f 01 sts 0x017F, r24
4b6: 8b e6 ldi r24, 0x6B ; 107
4b8: 90 e0 ldi r25, 0x00 ; 0
4ba: 90 93 82 01 sts 0x0182, r25
4be: 80 93 81 01 sts 0x0181, r24
4c2: 81 e0 ldi r24, 0x01 ; 1
4c4: 80 93 83 01 sts 0x0183, r24
4c8: 10 92 84 01 sts 0x0184, r1
4cc: 10 92 85 01 sts 0x0185, r1
4d0: 10 92 88 01 sts 0x0188, r1
4d4: 10 92 87 01 sts 0x0187, r1
// portB=PCintPort(2, 1,PCMSK1);
// index: portInputReg(*portInputRegister(index)),
// pcindex: PCICRbit(1 << pcindex)
// maskReg: portPCMask(maskReg)
PCintPort(int index,int pcindex, volatile uint8_t& maskReg) :
portInputReg(*portInputRegister(index)),
4d8: e6 e9 ldi r30, 0x96 ; 150
4da: f0 e0 ldi r31, 0x00 ; 0
4dc: 85 91 lpm r24, Z+
4de: 94 91 lpm r25, Z
portPCMask(maskReg),
PCICRbit(1 << pcindex),
portRisingPins(0),
portFallingPins(0),
firstPin(NULL)
4e0: 90 93 76 01 sts 0x0176, r25
4e4: 80 93 75 01 sts 0x0175, r24
4e8: 8c e6 ldi r24, 0x6C ; 108
4ea: 90 e0 ldi r25, 0x00 ; 0
4ec: 90 93 78 01 sts 0x0178, r25
4f0: 80 93 77 01 sts 0x0177, r24
4f4: 82 e0 ldi r24, 0x02 ; 2
4f6: 80 93 79 01 sts 0x0179, r24
4fa: 10 92 7a 01 sts 0x017A, r1
4fe: 10 92 7b 01 sts 0x017B, r1
502: 10 92 7e 01 sts 0x017E, r1
506: 10 92 7d 01 sts 0x017D, r1
// portB=PCintPort(2, 1,PCMSK1);
// index: portInputReg(*portInputRegister(index)),
// pcindex: PCICRbit(1 << pcindex)
// maskReg: portPCMask(maskReg)
PCintPort(int index,int pcindex, volatile uint8_t& maskReg) :
portInputReg(*portInputRegister(index)),
50a: e8 e9 ldi r30, 0x98 ; 152
50c: f0 e0 ldi r31, 0x00 ; 0
50e: 85 91 lpm r24, Z+
510: 94 91 lpm r25, Z
portPCMask(maskReg),
PCICRbit(1 << pcindex),
portRisingPins(0),
portFallingPins(0),
firstPin(NULL)
512: 90 93 6c 01 sts 0x016C, r25
516: 80 93 6b 01 sts 0x016B, r24
51a: 8d e6 ldi r24, 0x6D ; 109
51c: 90 e0 ldi r25, 0x00 ; 0
51e: 90 93 6e 01 sts 0x016E, r25
522: 80 93 6d 01 sts 0x016D, r24
526: 84 e0 ldi r24, 0x04 ; 4
528: 80 93 6f 01 sts 0x016F, r24
52c: 10 92 70 01 sts 0x0170, r1
530: 10 92 71 01 sts 0x0171, r1
534: 10 92 74 01 sts 0x0174, r1
538: 10 92 73 01 sts 0x0173, r1
53c: 08 95 ret
0000053e <__vector_16>:
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
53e: 1f 92 push r1
540: 0f 92 push r0
542: 0f b6 in r0, 0x3f ; 63
544: 0f 92 push r0
546: 11 24 eor r1, r1
548: 2f 93 push r18
54a: 3f 93 push r19
54c: 8f 93 push r24
54e: 9f 93 push r25
550: af 93 push r26
552: bf 93 push r27
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
554: 80 91 8d 01 lds r24, 0x018D
558: 90 91 8e 01 lds r25, 0x018E
55c: a0 91 8f 01 lds r26, 0x018F
560: b0 91 90 01 lds r27, 0x0190
unsigned char f = timer0_fract;
564: 30 91 8c 01 lds r19, 0x018C
m += MILLIS_INC;
f += FRACT_INC;
568: 23 e0 ldi r18, 0x03 ; 3
56a: 23 0f add r18, r19
if (f >= FRACT_MAX) {
56c: 2d 37 cpi r18, 0x7D ; 125
56e: 20 f4 brcc .+8 ; 0x578 <__vector_16+0x3a>
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
570: 01 96 adiw r24, 0x01 ; 1
572: a1 1d adc r26, r1
574: b1 1d adc r27, r1
576: 05 c0 rjmp .+10 ; 0x582 <__vector_16+0x44>
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
578: 26 e8 ldi r18, 0x86 ; 134
57a: 23 0f add r18, r19
m += 1;
57c: 02 96 adiw r24, 0x02 ; 2
57e: a1 1d adc r26, r1
580: b1 1d adc r27, r1
}
timer0_fract = f;
582: 20 93 8c 01 sts 0x018C, r18
timer0_millis = m;
586: 80 93 8d 01 sts 0x018D, r24
58a: 90 93 8e 01 sts 0x018E, r25
58e: a0 93 8f 01 sts 0x018F, r26
592: b0 93 90 01 sts 0x0190, r27
timer0_overflow_count++;
596: 80 91 91 01 lds r24, 0x0191
59a: 90 91 92 01 lds r25, 0x0192
59e: a0 91 93 01 lds r26, 0x0193
5a2: b0 91 94 01 lds r27, 0x0194
5a6: 01 96 adiw r24, 0x01 ; 1
5a8: a1 1d adc r26, r1
5aa: b1 1d adc r27, r1
5ac: 80 93 91 01 sts 0x0191, r24
5b0: 90 93 92 01 sts 0x0192, r25
5b4: a0 93 93 01 sts 0x0193, r26
5b8: b0 93 94 01 sts 0x0194, r27
}
5bc: bf 91 pop r27
5be: af 91 pop r26
5c0: 9f 91 pop r25
5c2: 8f 91 pop r24
5c4: 3f 91 pop r19
5c6: 2f 91 pop r18
5c8: 0f 90 pop r0
5ca: 0f be out 0x3f, r0 ; 63
5cc: 0f 90 pop r0
5ce: 1f 90 pop r1
5d0: 18 95 reti
000005d2 <micros>:
return m;
}
unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t;
5d2: 3f b7 in r19, 0x3f ; 63
cli();
5d4: f8 94 cli
m = timer0_overflow_count;
5d6: 80 91 91 01 lds r24, 0x0191
5da: 90 91 92 01 lds r25, 0x0192
5de: a0 91 93 01 lds r26, 0x0193
5e2: b0 91 94 01 lds r27, 0x0194
#if defined(TCNT0)
t = TCNT0;
5e6: 26 b5 in r18, 0x26 ; 38
#error TIMER 0 not defined
#endif
#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t < 255))
5e8: a8 9b sbis 0x15, 0 ; 21
5ea: 05 c0 rjmp .+10 ; 0x5f6 <micros+0x24>
5ec: 2f 3f cpi r18, 0xFF ; 255
5ee: 19 f0 breq .+6 ; 0x5f6 <micros+0x24>
m++;
5f0: 01 96 adiw r24, 0x01 ; 1
5f2: a1 1d adc r26, r1
5f4: b1 1d adc r27, r1
#else
if ((TIFR & _BV(TOV0)) && (t < 255))
m++;
#endif
SREG = oldSREG;
5f6: 3f bf out 0x3f, r19 ; 63
return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
5f8: 66 27 eor r22, r22
5fa: 78 2f mov r23, r24
5fc: 89 2f mov r24, r25
5fe: 9a 2f mov r25, r26
600: 62 0f add r22, r18
602: 71 1d adc r23, r1
604: 81 1d adc r24, r1
606: 91 1d adc r25, r1
608: 42 e0 ldi r20, 0x02 ; 2
60a: 66 0f add r22, r22
60c: 77 1f adc r23, r23
60e: 88 1f adc r24, r24
610: 99 1f adc r25, r25
612: 4a 95 dec r20
614: d1 f7 brne .-12 ; 0x60a <micros+0x38>
}
616: 08 95 ret
00000618 <delay>:
void delay(unsigned long ms)
{
618: cf 92 push r12
61a: df 92 push r13
61c: ef 92 push r14
61e: ff 92 push r15
620: cf 93 push r28
622: df 93 push r29
624: 6b 01 movw r12, r22
626: 7c 01 movw r14, r24
uint16_t start = (uint16_t)micros();
628: 0e 94 e9 02 call 0x5d2 ; 0x5d2 <micros>
62c: eb 01 movw r28, r22
while (ms > 0) {
62e: c1 14 cp r12, r1
630: d1 04 cpc r13, r1
632: e1 04 cpc r14, r1
634: f1 04 cpc r15, r1
636: 79 f0 breq .+30 ; 0x656 <delay+0x3e>
if (((uint16_t)micros() - start) >= 1000) {
638: 0e 94 e9 02 call 0x5d2 ; 0x5d2 <micros>
63c: 6c 1b sub r22, r28