macros -> subroutines/loops
Stefan Schuermans

Stefan Schuermans commited on 2019-06-21 08:45:29
Showing 1 changed files, with 158 additions and 200 deletions.


convert macros to subroutines and loops in order to make firmware shorter
in instruction memory, performance is almost the same
... ...
@@ -1,6 +1,5 @@
1 1
 ; bulb - BlinkenArea ultimate logo board
2
-; version 1.1.0 date 2012-06-10
3
-; Copyright (C) 2011-2012 Stefan Schuermans <stefan@blinkenarea.org>
2
+; Copyright (C) 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
4 3
 ; Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5 4
 
6 5
 ; ATtiny2313A, clock frequency: 8 MHz (internal oscillator)
... ...
@@ -40,15 +39,21 @@
40 39
 
41 40
 ; general purpose registers
42 41
 .def    TMP                     =       r16
43
-.def    CNT                     =       r17
44
-.def    DATA                    =       r18
42
+.def    TMP2                    =       r17
43
+.def    CNT                     =       r18
44
+.def    DATA                    =       r19
45
+.def    GRAY                    =       r20
45 46
 
46 47
 ; current mode
47
-.def    MODE                    =       r19
48
+.def    MODE                    =       r21
48 49
 .equ    MODE_ALL                =       0       ; play all animations
49 50
 .equ    MODE_SINGLE             =       1       ; play single animation only
50 51
 .equ    MODE_UNKNOWN            =       0xFF    ; unknown mode
51 52
 
53
+; current animation number and iterations
54
+.def    ANI_NO                  =       r22
55
+.def    ANI_IT                  =       r23
56
+
52 57
 
53 58
 
54 59
 .DSEG
... ...
@@ -61,125 +66,6 @@ FRAME:                  .BYTE   42
61 66
 
62 67
 
63 68
 
64
-.MACRO breqx
65
-        brne    NE
66
-        rjmp    @0
67
-NE:
68
-.ENDM
69
-
70
-
71
-
72
-; multiple rcalls in a row
73
-; parameters: label, N
74
-.MACRO rcall_N
75
-.IF @1 > 0
76
-        rcall   @0
77
-        rcall_N @0,@1 - 1
78
-.ENDIF
79
-.ENDM
80
-
81
-
82
-
83
-; check if to turn on pixel in subframe
84
-; parameter: grayscale value (1..15)
85
-; input: X = ptr to pixel data (0..7),
86
-;        DATA[7-1] = other pixels
87
-; output: X = ptr to pixel data of next pixel,
88
-;         DATA.7 = if _not_ to turn on pixel, DATA.[6-0] = old DATA[7-1]
89
-; changes: TMP, DATA, X
90
-; cycles: 4
91
-.MACRO PIXEL
92
-        ld      TMP,X+
93
-        cpi     TMP,@0
94
-        ror     DATA
95
-.ENDM
96
-
97
-
98
-
99
-; output row (black/white)
100
-; parameter: grayscale value (1..15)
101
-; input: X = ptr to pixel data (0..15)
102
-; output: -
103
-; changes: TMP, DATA
104
-; cycles: 32
105
-.MACRO ROW_BW
106
-        PIXEL   @0                      ; pixel 0
107
-        PIXEL   @0                      ; pixel 1
108
-        PIXEL   @0                      ; pixel 2
109
-        PIXEL   @0                      ; pixel 3
110
-        PIXEL   @0                      ; pixel 4
111
-        PIXEL   @0                      ; pixel 5
112
-        PIXEL   @0                      ; pixel 6
113
-        subi    XL,7                    ;   XH not there on ATtiny2313
114
-        lsr     DATA                    ; ensure remaining bit stays high
115
-                                        ;   (pull-up for unused pin)
116
-        com     DATA
117
-        out     COL_PORT,DATA
118
-.ENDM
119
-
120
-
121
-
122
-; wait n * 64 cycles
123
-; parameter: n
124
-; input: -
125
-; output: -
126
-; changes: TMP
127
-; cycles: n * 64
128
-.MACRO WAIT64_N
129
-.IF @0 > 0
130
-        rcall           WAIT64
131
-        WAIT64_N        @0 - 1
132
-.ENDIF
133
-.ENDM
134
-
135
-
136
-
137
-; output row for grayscale (black/white) and wait
138
-; parameter: grayscale value (1..15)
139
-; input: X = ptr to pixel data (0..15)
140
-; output: -
141
-; changes: TMP, DATA
142
-; cycles: 32 + (grayscale - 1) * 64
143
-.MACRO ROW_BW_WAIT
144
-        ROW_BW          @0
145
-        WAIT64_N        @0 - 1
146
-.ENDM
147
-
148
-
149
-
150
-; turn off row (with same timing as ROW_BW)
151
-; input: -
152
-; output: -
153
-; changes: TMP
154
-; cycles: 32
155
-.MACRO ROW_OFF
156
-        ldi     TMP,10
157
-ROW_OFF_LOOP:
158
-        dec     TMP
159
-        brne    ROW_OFF_LOOP
160
-        ldi     TMP,0x80                ; ensure remaining bit stays high
161
-                                        ;   (pull-up for unused pin)
162
-        out     COL_PORT,TMP
163
-.ENDM
164
-
165
-
166
-
167
-; play an animation N times (mode 0) or infinitely (mode 1)
168
-; parameters: animation function, N, animation number
169
-.MACRO PL_ANIM
170
-PL_ANIM_LOOP:
171
-        ; play animation N times
172
-        rcall_N @0,@1 - 1
173
-        ; read new mode
174
-        ldi     CNT,@2
175
-        rcall   MODE_READ
176
-        ; keep playing animation in mode 1
177
-        cpi     MODE,MODE_SINGLE
178
-        breq    PL_ANIM_LOOP
179
-.ENDM
180
-
181
-
182
-
183 69
 .CSEG
184 70
 .ORG    0x000
185 71
         rjmp    ENTRY                   ; RESET
... ...
@@ -244,43 +130,85 @@ ENTRY:
244 130
 
245 131
 
246 132
 
247
-; wait 64 cycles
133
+; wait 61 cycles
248 134
 ; input: -
249 135
 ; output: -
250 136
 ; changes: TMP
251
-; cycles: 64 (including rcall and ret)
252
-WAIT64:
253
-        ldi     TMP,19
254
-WAIT64_LOOP:
137
+; cycles: 61 (including rcall and ret)
138
+WAIT61:
139
+        ldi     TMP,18
140
+WAIT61_LOOP:
255 141
         dec     TMP
256
-        brne    WAIT64_LOOP
142
+        brne    WAIT61_LOOP
257 143
 ; done
258 144
         ret
259 145
 
260 146
 
261 147
 
148
+; output row for grayscale (black/white) and wait
149
+; input: X = ptr to pixel data (0..15)
150
+;        GRAY = grayscale value (1..15)
151
+; output: -
152
+; changes: TMP, TMP2, DATA
153
+; cycles: GRAY * 64 + 1 (including rcall and ret)
154
+ROW_BW_WAIT:
155
+; get data for LEDs
156
+        ldi     TMP2,7                  ; 7 pixels
157
+ROW_BW_WAIT_PIXEL:
158
+        ld      TMP,X+                  ; get pixel value
159
+        cp      TMP,GRAY                ; compare with grayscale value
160
+        ror     DATA                    ; store result as output bit
161
+        dec     TMP2                    ; next pixel
162
+        brne    ROW_BW_WAIT_PIXEL
163
+; restore data pointer
164
+        subi    XL,7                    ;   XH not there on ATtiny2313
165
+; output
166
+        lsr     DATA                    ; ensure remaining bit stays high
167
+                                        ;   (pull-up for unused pin)
168
+        com     DATA
169
+        out     COL_PORT,DATA
170
+; wait 5 + (GRAY - 1) * 64
171
+        mov     TMP2,GRAY
172
+        rjmp    ROW_BW_WAIT_LOOP_ENTRY
173
+ROW_BW_WAIT_LOOP:
174
+        rcall   WAIT61
175
+ROW_BW_WAIT_LOOP_ENTRY:
176
+        dec     TMP2
177
+        brne    ROW_BW_WAIT_LOOP
178
+        ret
179
+
180
+
181
+
182
+; turn off row (with same timing as ROW_BW_WAIT)
183
+; input: -
184
+; output: -
185
+; changes: TMP
186
+; cycles: 60 (including rcall and ret)
187
+ROW_OFF:
188
+        ldi     TMP,17
189
+ROW_OFF_LOOP:
190
+        dec     TMP
191
+        brne    ROW_OFF_LOOP
192
+        ldi     TMP,0x80                ; ensure remaining bit stays high
193
+                                        ;   (pull-up for unused pin)
194
+        out     COL_PORT,TMP
195
+        ret
196
+
197
+
198
+
262 199
 ; output row (grayscales)
263 200
 ; input: X = ptr to pixel data (0..15)
264 201
 ; output: -
265
-; changes: TMP, DATA
266
-; cycles: 7269 (including rcall and ret)
202
+; changes: TMP, TMP2, DATA
203
+; cycles: 7822 (including rcall and ret)
267 204
 ROW_GRAY:
268
-        ROW_BW_WAIT     1
269
-        ROW_BW_WAIT     2
270
-        ROW_BW_WAIT     3
271
-        ROW_BW_WAIT     4
272
-        ROW_BW_WAIT     5
273
-        ROW_BW_WAIT     6
274
-        ROW_BW_WAIT     7
275
-        ROW_BW_WAIT     8
276
-        ROW_BW_WAIT     9
277
-        ROW_BW_WAIT     10
278
-        ROW_BW_WAIT     11
279
-        ROW_BW_WAIT     12
280
-        ROW_BW_WAIT     13
281
-        ROW_BW_WAIT     14
282
-        ROW_BW_WAIT     15
283
-        ROW_OFF
205
+        ldi     GRAY,1
206
+ROW_GRAY_LOOP:
207
+        rcall   ROW_BW_WAIT
208
+        inc     GRAY
209
+        cpi     GRAY,16
210
+        brlo    ROW_GRAY_LOOP
211
+        rcall   ROW_OFF
284 212
 ; done
285 213
         ret
286 214
 
... ...
@@ -289,7 +217,7 @@ ROW_GRAY:
289 217
 ; output a frame
290 218
 ; input: FRAME = pixel data (0..15)
291 219
 ; output: -
292
-; changes: TMP, CNT, DATA, X
220
+; changes: TMP, TMP2, CNT, DATA, X
293 221
 ; cycles: 43682 (including rcall and ret)
294 222
 ; time: 5.5ms
295 223
 OUT_FRAME:
... ...
@@ -319,7 +247,7 @@ OUT_FRAME_LOOP:
319 247
 ; input: FRAME = pixel data (0..15)
320 248
 ;        TMP = time to show frame (1..255, in 5.5 ms steps)
321 249
 ; output: -
322
-; changes: X, TMP
250
+; changes: X, TMP, TMP2
323 251
 ; time: TMP * 5.5 ms
324 252
 OUT_FRAME_TIME:
325 253
 ; output frame
... ...
@@ -455,7 +383,7 @@ DRAW_BW_WORM_END:
455 383
 ; blink animation
456 384
 ; input: -
457 385
 ; output: -
458
-; changes: X, FRAME, CNT, DATA, TMP
386
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
459 387
 ANIM_BLINK:
460 388
 ; off
461 389
         ldi     DATA,0                  ; minimum color
... ...
@@ -475,7 +403,7 @@ ANIM_BLINK:
475 403
 ; fade up and down animation
476 404
 ; input: -
477 405
 ; output: -
478
-; changes: X, FRAME, CNT, DATA, TMP
406
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
479 407
 ANIM_FADE:
480 408
 ; fade up
481 409
         ldi     DATA,0                  ; start dark
... ...
@@ -502,7 +430,7 @@ ANIM_FADE_DOWN:
502 430
 ; flicker animation
503 431
 ; input: -
504 432
 ; output: -
505
-; changes: X, FRAME, CNT, DATA, TMP
433
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
506 434
 ANIM_FLICKER:
507 435
 ; even pixels
508 436
         rcall   CLEAR                   ; clear
... ...
@@ -534,7 +462,7 @@ ANIM_FLICKER_ODD:
534 462
 ; wobble animation
535 463
 ; input: -
536 464
 ; output: -
537
-; changes: X, FRAME, CNT, DATA, TMP
465
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
538 466
 ANIM_WOBBLE:
539 467
 ; even pixels up, odd pixels down
540 468
         ldi     DATA,0                  ; even pixels start dark
... ...
@@ -576,7 +504,7 @@ ANIM_WOBBLE_DOWN_DRAW:
576 504
 ; run animation
577 505
 ; input: -
578 506
 ; output: -
579
-; changes: X, FRAME, CNT, DATA, TMP
507
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
580 508
 ANIM_RUN:
581 509
         ldi     CNT,255                 ; start before 1st pixel
582 510
 ANIM_RUN_LOOP:
... ...
@@ -596,7 +524,7 @@ ANIM_RUN_LOOP:
596 524
 ; backwards run animation
597 525
 ; input: -
598 526
 ; output: -
599
-; changes: X, FRAME, CNT, DATA, TMP
527
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
600 528
 ANIM_BW_RUN:
601 529
         ldi     CNT,42                  ; start after last pixel
602 530
 ANIM_BW_RUN_LOOP:
... ...
@@ -616,7 +544,7 @@ ANIM_BW_RUN_LOOP:
616 544
 ; worm animation
617 545
 ; input: -
618 546
 ; output: -
619
-; changes: X, FRAME, CNT, DATA, TMP
547
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
620 548
 ANIM_WORM:
621 549
         ldi     CNT,255                 ; worm starts before 1st pixel
622 550
 ANIM_WORM_LOOP:
... ...
@@ -635,7 +563,7 @@ ANIM_WORM_LOOP:
635 563
 ; backwards worm animation
636 564
 ; input: -
637 565
 ; output: -
638
-; changes: X, FRAME, CNT, DATA, TMP
566
+; changes: X, FRAME, CNT, DATA, TMP, TMP2
639 567
 ANIM_BW_WORM:
640 568
         ldi     CNT,56                  ; worm starts behind frame
641 569
                                         ;   head not yet visible
... ...
@@ -688,6 +616,28 @@ MODE_READ_NOT_0_TO_1:
688 616
 
689 617
 
690 618
 
619
+; animation table: animation function, iteration count (<= 255)
620
+ANIM_TAB:
621
+        .dw     ANIM_BLINK
622
+        .dw     3
623
+        .dw     ANIM_WORM
624
+        .dw     3
625
+        .dw     ANIM_FLICKER
626
+        .dw     10
627
+        .dw     ANIM_BW_RUN
628
+        .dw     3
629
+        .dw     ANIM_FADE
630
+        .dw     2
631
+        .dw     ANIM_BW_WORM
632
+        .dw     3
633
+        .dw     ANIM_WOBBLE
634
+        .dw     5
635
+        .dw     ANIM_RUN
636
+        .dw     3
637
+ANIM_TAB_END:
638
+
639
+
640
+
691 641
 ; main program
692 642
 MAIN:
693 643
         wdr
... ...
@@ -699,56 +649,64 @@ MAIN:
699 649
         ldi     TMP,0                   ; set EEPROM address
700 650
         out     EEARL,TMP
701 651
         sbi     EECR,EERE               ; start EEPROM read
702
-        in      CNT,EEDR                ; get read value
703
-        mov     TMP,CNT                 ; check if high nibble contains NOTed
652
+        in      ANI_NO,EEDR                ; get read value
653
+        mov     TMP,ANI_NO              ; check if high nibble contains NOTed
704 654
         com     TMP                     ;   value
705 655
         swap    TMP
706
-        cp      CNT,TMP
707
-        brne    MAIN_FIRST_ANIM_END
708
-        andi    CNT,0x0F                ; throw away check value in high nibble
709
-; jump to first animation
710
-        cpi     CNT,0
711
-        breq    MAIN_FIRST_0
712
-        cpi     CNT,1
713
-        breq    MAIN_FIRST_1
714
-        cpi     CNT,2
715
-        breq    MAIN_FIRST_2
716
-        cpi     CNT,3
717
-        breq    MAIN_FIRST_3
718
-        cpi     CNT,4
719
-        breq    MAIN_FIRST_4
720
-        cpi     CNT,5
721
-        breq    MAIN_FIRST_5
722
-        cpi     CNT,6
723
-        breq    MAIN_FIRST_6
724
-        cpi     CNT,7
725
-        breq    MAIN_FIRST_7
726
-MAIN_FIRST_ANIM_END:
727
-
656
+        cp      ANI_NO,TMP
657
+        brne    MAIN_FIRST_ANIM_INVALID
658
+        andi    ANI_NO,0x0F             ; throw away check value in high nibble
659
+        cpi     ANI_NO,(ANIM_TAB_END - ANIM_TAB) / 2
660
+        brlo    MAIN_FIRST_ANIM_OK
661
+MAIN_FIRST_ANIM_INVALID:
662
+        ldi     ANI_NO,0
663
+MAIN_FIRST_ANIM_OK:
664
+; first iteration of animation (into DATA)
665
+        ldi     ANI_IT,0
728 666
 
667
+; main loop
729 668
 MAIN_LOOP:
730 669
         wdr
731 670
 
732
-; main loop
671
+; load pointer to animation function and repetition count from table
672
+        ldi     ZL,low(2 * ANIM_TAB)
673
+        ldi     ZH,high(2 * ANIM_TAB)
674
+        mov     TMP,ANI_NO
675
+        lsl     TMP
676
+        lsl     TMP
677
+        add     ZL,TMP
678
+        clr     TMP
679
+        adc     ZH,TMP
680
+        lpm     DATA,Z+                 ; address of function -> TMP:DATA
681
+        lpm     TMP,Z+
682
+        lpm     CNT,Z+                  ; iteration count -> CNT
683
+        mov     ZL,DATA                 ; address of function  -> Z
684
+        mov     ZH,TMP
685
+; save iteration count
686
+        push    CNT
687
+; call animation
688
+        icall
689
+; read new mode
690
+        mov     CNT,ANI_NO
691
+        rcall   MODE_READ
692
+; restore iteration count
693
+        pop     CNT
733 694
 
734
-MAIN_FIRST_0:
735
-        PL_ANIM ANIM_BLINK,3,0
736
-MAIN_FIRST_1:
737
-        PL_ANIM ANIM_WORM,3,1
738
-MAIN_FIRST_2:
739
-        PL_ANIM ANIM_FLICKER,10,2
740
-MAIN_FIRST_3:
741
-        PL_ANIM ANIM_BW_RUN,3,3
742
-MAIN_FIRST_4:
743
-        PL_ANIM ANIM_FADE,2,4
744
-MAIN_FIRST_5:
745
-        PL_ANIM ANIM_BW_WORM,3,5
746
-MAIN_FIRST_6:
747
-        PL_ANIM ANIM_WOBBLE,5,6
748
-MAIN_FIRST_7:
749
-        PL_ANIM ANIM_RUN,3,7
695
+; keep playing animation in single animation mode
696
+        cpi     MODE,MODE_SINGLE
697
+        breq    MAIN_NEXT_END
698
+; next iteration
699
+        inc     ANI_IT
700
+        cp      ANI_IT,CNT
701
+        brlo    MAIN_NEXT_END
702
+        clr     ANI_IT
703
+; next animation
704
+        inc     ANI_NO
705
+        cpi     ANI_NO,(ANIM_TAB_END - ANIM_TAB) / 2
706
+        brlo    MAIN_NEXT_END
707
+        clr     ANI_NO
708
+MAIN_NEXT_END:
750 709
 
751 710
 ; bottom of main loop
752
-
753 711
         rjmp     MAIN_LOOP
754 712
 
755 713