3f64c20e103f82343ff10146bb409b28e4239c2c
Stefan Schuermans initial version of firmware

Stefan Schuermans authored 5 years ago

1) ; Chaosknoten - animated logo board
2) ; Copyright (C) 2019 Stefan Schuermans <stefan@blinkenarea.org>
3) ; Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
4) 
5) ; ATtiny2313A, clock frequency: 8 MHz (internal oscillator)
6) 
7) ; PA0: unused
8) ; PA1: unused
9) ; PA2: reset
10) ; PB0: column 0 output (output, low)
11) ; PB1: column 1 output (output, low)
12) ; PB2: column 2 output (output, low)
13) ; PB3: column 3 output (output, low)
14) ; PB4: column 4 output (output, low)
15) ; PB5: column 5 output (output, low)
16) ; PB6: column 6 output (output, low)
17) ; PB7: unused (input, pull-up enabled)
18) ; PD0: row 0 output (output, high)
19) ; PD1: row 1 output (output, high)
20) ; PD2: row 2 output (output, high)
21) ; PD3: row 3 output (output, high)
22) ; PD4: row 4 output (output, high)
23) ; PD5: row 5 output (output, high)
24) ; PD6: mode switch (input, pull-up enabled)
25) 
26) 
27) 
28) .INCLUDE        "tn2313def.inc"
29) 
30) 
31) 
32) ; IO pins
33) .equ    COL_PORT                =       PORTB   ; column outputs
34) .equ    ROW_PORT                =       PORTD   ; row outputs
35) .equ    MODE_SW_PIN             =       PIND
36) .equ    MODE_SW_BIT             =       6
37) 
38) 
39) 
40) ; general purpose registers
41) .def    TMP                     =       r16
42) .def    TMP2                    =       r17
43) .def    CNT                     =       r18
44) .def    DATA                    =       r19
45) .def    GRAY                    =       r20
46) 
47) ; current mode
48) .def    MODE                    =       r21
49) .equ    MODE_ALL                =       0       ; play all animations
50) .equ    MODE_SINGLE             =       1       ; play single animation only
51) .equ    MODE_UNKNOWN            =       0xFF    ; unknown mode
52) 
53) ; current animation number and iterations
54) .def    ANI_NO                  =       r22
55) .def    ANI_IT                  =       r23
56) 
57) 
58) 
59) .DSEG
60) .ORG    0x060
61) 
62) 
63) 
64) ; current frame
65) FRAME:                  .BYTE   42
66) 
67) 
68) 
69) .CSEG
70) .ORG    0x000
71)         rjmp    ENTRY                   ; RESET
72)         reti                            ; INT0
73)         reti                            ; INT1
74)         reti                            ; TIMER1_CAPT
75)         reti                            ; TIMER1_COMPA
76)         reti                            ; TIMER1_OVF
77)         reti                            ; TIMER0_OVF
78)         reti                            ; USART0_RX
79)         reti                            ; USART0_UDRE
80)         reti                            ; USART0_TX
81)         reti                            ; ANALOG_COMP
82)         reti                            ; PC_INT0
83)         reti                            ; TIMER1_COMPB
84)         reti                            ; TIMER0_COMPA
85)         reti                            ; TIMER0_COMPB
86)         reti                            ; USI_START
87)         reti                            ; USI_OVERFLOW
88)         reti                            ; EE_READY
89)         reti                            ; WDT
90)         reti                            ; PC_INT1
91)         reti                            ; PC_INT2
92) 
93) 
94) 
95) ; code entry point
96) ENTRY:
97) ; set system clock prescaler to 1:1
98)         ldi     TMP,1<<CLKPCE
99)         out     CLKPR,TMP
100)         ldi     TMP,0
101)         out     CLKPR,TMP
102) ; initialize output ports
103)         ldi     TMP,0x00                ; PA[01] to output, low
104)         out     PORTA,TMP
105)         ldi     TMP,0x03
106)         out     DDRA,TMP
107)         ldi     TMP,0x80                ; PB[0-6] to output, low - PB7 to input, pull-up enabled
108)         out     PORTB,TMP
109)         ldi     TMP,0x7F
110)         out     DDRB,TMP
111)         ldi     TMP,0x7F                ; PD[0-5] to output, high - PD6 to input, pull-up enabled
112)         out     PORTD,TMP
113)         ldi     TMP,0x3F
114)         out     DDRD,TMP
115) ; initialize stack pointer
116)         ldi     TMP,RAMEND
117)         out     SPL,TMP
118) ; enable watchdog (64ms)
119)         wdr
120)         ldi     TMP,1<<WDCE|1<<WDE
121)         out     WDTCR,TMP
122)         ldi     TMP,1<<WDE|1<<WDP1
123)         out     WDTCR,TMP
124)         wdr
125) ; disable analog comparator
126)         ldi     TMP,1<<ACD
127)         out     ACSR,TMP
128) ; jump to main program
129)         rjmp    MAIN
130) 
131) 
132) 
133) ; wait 61 cycles
134) ; input: -
135) ; output: -
136) ; changes: TMP
137) ; cycles: 61 (including rcall and ret)
138) WAIT61:
139)         ldi     TMP,18
140) WAIT61_LOOP:
141)         dec     TMP
142)         brne    WAIT61_LOOP
143) ; done
144)         ret
145) 
146) 
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) 
199) ; output row (grayscales)
200) ; input: X = ptr to pixel data (0..15)
201) ; output: -
202) ; changes: TMP, TMP2, DATA
203) ; cycles: 7822 (including rcall and ret)
204) ; time: 1ms
205) ROW_GRAY:
206)         ldi     GRAY,1
207) ROW_GRAY_LOOP:
208)         rcall   ROW_BW_WAIT
209)         inc     GRAY
210)         cpi     GRAY,16
211)         brlo    ROW_GRAY_LOOP
212)         rcall   ROW_OFF
213) ; done
214)         ret
215) 
216) 
217) 
218) ; output a frame
219) ; input: FRAME = pixel data (0..15)
220) ; output: -
221) ; changes: TMP, TMP2, CNT, DATA, X
222) ; time: 6ms
223) OUT_FRAME:
224)         wdr
225)         ldi     XL,low(FRAME)           ; ptr to pixel data
226)                                         ;   XH not there on ATtiny2313
227)         ldi     CNT,0x01                ; bitmask loop over rows
228) OUT_FRAME_LOOP:
229)         mov     TMP,CNT                 ; select row
230)         com     TMP
231)         andi    TMP,0x3F
232)         ori     TMP,0x40                ; ensure bit 6 stays high
233)                                         ;   (pull-up for switch input)
234)         out     ROW_PORT,TMP
235)         rcall   ROW_GRAY                ; display row
236)         subi    XL,-7                   ; ptr to next row
237)                                         ;   XH not there on ATtiny2313
238)         lsl     CNT                     ; bitmask loop over rows
239)         cpi     CNT,0x40
240)         brne    OUT_FRAME_LOOP
241) ; done
242)         ret
243) 
244) 
245) 
246) ; output a frame for some time
247) ; input: FRAME = pixel data (0..15)
248) ;        TMP = time to show frame (1..255, in 6 ms steps)
249) ; output: -
250) ; changes: X, TMP, TMP2
251) ; time: TMP * 6 ms
252) OUT_FRAME_TIME:
253) ; output frame
254)         push    TMP
255)         push    CNT
256)         push    DATA
257)         rcall   OUT_FRAME               ; 6 ms
258)         pop     DATA
259)         pop     CNT
260)         pop     TMP
261) ; loop
262)         dec     TMP
263)         brne    OUT_FRAME_TIME
264) ; done
265)         ret
266) 
267) 
268) 
269) ; clear frame
270) ; input: -
271) ; output: -
272) ; changes: X, FRAME, TMP
273) ; time: short
274) CLEAR:
275)         ldi     XL,low(FRAME)           ; ptr to pixel data
276)                                         ;   XH not there on ATtiny2313
277)         clr     TMP
278) CLEAR_LOOP:
279)         st      X+,TMP                  ; clear pixel
280)         cpi     XL,low(FRAME)+42        ; bottom of loop
281)                                         ;   XH not there on ATtiny2313
282)         brne    CLEAR_LOOP
283) ; done
284)         ret
285) 
286) 
287) 
288) ; set frame to solid color
289) ; input: DATA = value (0..15)
290) ; output: -
291) ; changes: X, FRAME
292) ; time: short
293) SET_COLOR:
294)         ldi     XL,low(FRAME)           ; ptr to pixel data
295)                                         ;   XH not there on ATtiny2313
296) SET_COLOR_LOOP:
297)         st      X+,DATA                 ; set pixel value
298)         cpi     XL,low(FRAME)+42        ; bottom of loop
299)                                         ;   XH not there on ATtiny2313
300)         brne    SET_COLOR_LOOP
301) ; done
302)         ret
303) 
304) 
305) 
306) ; set pixel
307) ; input: CNT = pixel number (0..41, nothing is done for 42..255)
308) ;        DATA = value (0..15)
309) ; output: -
310) ; changes: X, FRAME, TMP
311) ; time: short
312) SET_PIXEL:
313)         cpi     CNT,42                  ; invalid pixel number -> done
314)         brsh    SET_PIXEL_END
315)         ldi     XL,low(FRAME)           ; ptr to pixel (base + offset)
316)         add     XL,CNT                  ;   XH not there on ATtiny2313
317)         st      X,DATA                  ; set pixel
318) SET_PIXEL_END:
319) ; done
320)         ret
321) 
322) 
323) 
324) ; draw worm
325) ; input: CNT = head of worm (0..55)
326) ; output: -
327) ; changes: X, FRAME, TMP, DATA
328) ; time: short
329) DRAW_WORM:
330)         cpi     CNT,56                  ; invalid head pos -> done
331)         brsh    DRAW_WORM_END
332)         ldi     XL,low(FRAME)+1         ; ptr to before head
333)         add     XL,CNT                  ;   XH not there on ATtiny2313
334)         ldi     DATA,15                 ; head is full on
335)         cpi     CNT,42                  ; head pos in frame -> go
336)         brlo    DRAW_WORM_LOOP
337)         mov     TMP,CNT                 ; TMP := invisible pixels
338)         subi    TMP,41
339)         sub     XL,TMP                  ; skip invisible pixels
340)         sub     DATA,TMP                ;   XH not there on ATtiny2313
341) DRAW_WORM_LOOP:
342)         st      -X,DATA                 ; set pixel, go back
343)         cpi     XL,low(FRAME)           ; 1st pixel -> done
344)         breq    DRAW_WORM_END           ;   XH not there on ATtiny2313
345)         dec     DATA                    ; next pixel darker
346)         brne    DRAW_WORM_LOOP          ; loop
347) DRAW_WORM_END:
348) ; done
349)         ret
350) 
351) 
352) 
353) ; draw backwards worm
354) ; input: CNT = tail of worm (0..55)
355) ; output: -
356) ; changes: X, FRAME, TMP, DATA
357) ; time: short
358) DRAW_BW_WORM:
359)         cpi     CNT,56                  ; invalid tail pos -> done
360)         brsh    DRAW_BW_WORM_END
361)         ldi     XL,low(FRAME)+1         ; ptr to before tail
362)         add     XL,CNT                  ;   XH not there on ATtiny2313
363)         ldi     DATA,1                  ; tail is minimum on
364)         cpi     CNT,42                  ; tail pos in frame -> go
365)         brlo    DRAW_BW_WORM_LOOP
366)         mov     TMP,CNT                 ; TMP := invisible pixels
367)         subi    TMP,41
368)         sub     XL,TMP                  ; skip invisible pixels
369)         add     DATA,TMP                ;   XH not there on ATtiny2313
370) DRAW_BW_WORM_LOOP:
371)         st      -X,DATA                 ; set pixel, go back
372)         cpi     XL,low(FRAME)           ; 1st pixel -> done
373)         breq    DRAW_BW_WORM_END        ;   XH not there on ATtiny2313
374)         inc     DATA                    ; next pixel brighter
375)         cpi     DATA,16                 ; loop
376)         brne    DRAW_BW_WORM_LOOP
377) DRAW_BW_WORM_END:
378) ; done
379)         ret
380) 
381) 
382) 
383) ; blink animation
384) ; input: -
385) ; output: -
386) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
387) ANIM_BLINK:
388) ; off
389)         ldi     DATA,0                  ; minimum color
390)         rcall   SET_COLOR               ; paint
391)         ldi     TMP,100                 ; show frame 600 ms
392)         rcall   OUT_FRAME_TIME
393) ; on
394)         ldi     DATA,15                 ; maximum color
395)         rcall   SET_COLOR               ; paint
396)         ldi     TMP,100                 ; show frame 600 ms
397)         rcall   OUT_FRAME_TIME
398) ; done
399)         ret
400) 
401) 
402) 
403) ; fade up and down animation
404) ; input: -
405) ; output: -
406) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
407) ANIM_FADE:
408) ; fade up
409)         ldi     DATA,0                  ; start dark
410) ANIM_FADE_UP:
411)         rcall   SET_COLOR               ; paint
412)         ldi     TMP,10                  ; show frame 60 ms
413)         rcall   OUT_FRAME_TIME
414)         inc     DATA                    ; fade up
415)         cpi     DATA,15                 ; loop until almost full on
416)         brne    ANIM_FADE_UP
417) ; fade down
418) ANIM_FADE_DOWN:
419)         rcall   SET_COLOR               ; paint
420)         ldi     TMP,10                  ; show frame 60 ms
421)         rcall   OUT_FRAME_TIME
422)         dec     DATA                    ; fade up
423)         cpi     DATA,255                ; loop until full off
424)         brne    ANIM_FADE_DOWN
425) ; done
426)         ret
427) 
428) 
429) 
430) ; flicker animation
431) ; input: -
432) ; output: -
433) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
434) ANIM_FLICKER:
435) ; even pixels
436)         rcall   CLEAR                   ; clear
437)         ldi     DATA,15                 ; even pixels to maximum
438)         ldi     CNT,0
439) ANIM_FLICKER_EVEN:
440)         rcall   SET_PIXEL
441)         subi    CNT,-2                  ; move two pixels
442)         cpi     CNT,42                  ; loop
443)         brlo    ANIM_FLICKER_EVEN
444)         ldi     TMP,40                  ; show frame 240 ms
445)         rcall   OUT_FRAME_TIME
446) ; odd pixels
447)         rcall   CLEAR                   ; clear
448)         ldi     DATA,15                 ; odd pixels to maximum
449)         ldi     CNT,1
450) ANIM_FLICKER_ODD:
451)         rcall   SET_PIXEL
452)         subi    CNT,-2                  ; move two pixels
453)         cpi     CNT,42                  ; loop
454)         brlo    ANIM_FLICKER_ODD
455)         ldi     TMP,40                  ; show frame 240 ms
456)         rcall   OUT_FRAME_TIME
457) ; done
458)         ret
459) 
460) 
461) 
462) ; wobble animation
463) ; input: -
464) ; output: -
465) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
466) ANIM_WOBBLE:
467) ; even pixels up, odd pixels down
468)         ldi     DATA,0                  ; even pixels start dark
469) ANIM_WOBBLE_UP:
470)         ldi     CNT,0
471) ANIM_WOBBLE_UP_DRAW:
472)         rcall   SET_PIXEL
473)         inc     CNT                     ; next pixel
474)         ldi     TMP,0x0F                ; invert color
475)         eor     DATA,TMP
476)         cpi     CNT,42                  ; loop
477)         brlo    ANIM_WOBBLE_UP_DRAW
478)         ldi     TMP,10                  ; show frame 60 ms
479)         rcall   OUT_FRAME_TIME
480)         inc     DATA                    ; next color: brighter
481)         cpi     DATA,16
482)         brlo    ANIM_WOBBLE_UP
483) ; even pixels down, odd pixels up
484)         ldi     DATA,15                 ; even pixels start full
485) ANIM_WOBBLE_DOWN:
486)         ldi     CNT,0
487) ANIM_WOBBLE_DOWN_DRAW:
488)         rcall   SET_PIXEL
489)         inc     CNT                     ; next pixel
490)         ldi     TMP,0x0F                ; invert color
491)         eor     DATA,TMP
492)         cpi     CNT,42                  ; loop
493)         brlo    ANIM_WOBBLE_DOWN_DRAW
494)         ldi     TMP,10                  ; show frame 60 ms
495)         rcall   OUT_FRAME_TIME
496)         dec     DATA                    ; next color: darker
497)         cpi     DATA,16
498)         brlo    ANIM_WOBBLE_DOWN
499) ; done
500)         ret
501) 
502) 
503) 
504) ; run animation
505) ; input: -
506) ; output: -
507) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
508) ANIM_RUN:
509)         ldi     CNT,255                 ; start before 1st pixel
510) ANIM_RUN_LOOP:
511)         rcall   CLEAR                   ; clear
512)         ldi     DATA,15                 ; current pixel full on
513)         rcall   SET_PIXEL
514)         ldi     TMP,10                  ; show frame 60 ms
515)         rcall   OUT_FRAME_TIME
516)         inc     CNT                     ; next pixel
517)         cpi     CNT,43                  ; loop until after last pixel
518)         brne    ANIM_RUN_LOOP
519) ; done
520)         ret
521) 
522) 
523) 
524) ; backwards run animation
525) ; input: -
526) ; output: -
527) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
528) ANIM_BW_RUN:
529)         ldi     CNT,42                  ; start after last pixel
530) ANIM_BW_RUN_LOOP:
531)         rcall   CLEAR                   ; clear
532)         ldi     DATA,15                 ; current pixel full on
533)         rcall   SET_PIXEL
534)         ldi     TMP,10                  ; show frame 60 ms
535)         rcall   OUT_FRAME_TIME
536)         dec     CNT                     ; previous pixel
537)         cpi     CNT,255                 ; loop until before 1st pixel
538)         brne    ANIM_BW_RUN_LOOP
539) ; done
540)         ret
541) 
542) 
543) 
544) ; worm animation
545) ; input: -
546) ; output: -
547) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
548) ANIM_WORM:
549)         ldi     CNT,255                 ; worm starts before 1st pixel
550) ANIM_WORM_LOOP:
551)         rcall   CLEAR                   ; draw worm
552)         rcall   DRAW_WORM
553)         ldi     TMP,10                  ; show frame 60 ms
554)         rcall   OUT_FRAME_TIME
555)         inc     CNT                     ; advance worm
556)         cpi     CNT,57                  ; loop until has exits
557)         brne    ANIM_WORM_LOOP
558) ; done
559)         ret
560) 
561) 
562) 
563) ; backwards worm animation
564) ; input: -
565) ; output: -
566) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
567) ANIM_BW_WORM:
568)         ldi     CNT,56                  ; worm starts behind frame
569)                                         ;   head not yet visible
570) ANIM_BW_WORM_LOOP:
571)         rcall   CLEAR                   ; draw backwards worm
572)         rcall   DRAW_BW_WORM
573)         ldi     TMP,10                  ; show frame 60 ms
574)         rcall   OUT_FRAME_TIME
575)         dec     CNT                     ; advance worm backwards
576)         cpi     CNT,254                 ; loop until worm has exited
577)         brne    ANIM_BW_WORM_LOOP
578) ; done
579)         ret
580) 
581) 
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

582) ; movie data format
583) ;   movie = frame ... frame end
584) ;   frame = 0x0_ ... -> plain frame
585) ;           0x1_ ... -> rle (run length encoded) frame
586) ;           0x2_ ... -> back reference
587) ;   plain frame = duration_high (0x00..0x0F), duration_low (0x00..0xFF),
588) ;                 21 * ( pixel (0x00..0x0F)) << 4 | pixel (0x00..0x0F) )
589) ;   rle frame = 0x10 | duration_high (0x00..0x0F), duration_low (0x00..0xFF),
590) ;               rle entry, ..., rle_entry (until 42 pixels are encoded)
591) ;   rle_entry = repeat (0x00..0x0F) << 4 | value (0x00..0x0F)
592) ;               meaning: repeat + 1 pixels of value
593) ;   back reference = 0x20 | back_high (0x00..0x0F), back_low (0x00..0xFF)
594) ;                    meaning: read frame from earlier position,
595) ;                             frame data start = pos after back ref - back
596) ;   end = 0xF_
597) 
598) 
599) 
600) ; play animation - process code and following section
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

601) ; input: Z = pointer to movie data
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

602) ;        TMP2 = 0 -> initial call, 1 -> nested call
603) ; output: Z = pointer to behind processed movie data (only for initial call)
604) ;         TMP = 0 -> go on, 1 -> end
605) ; changes: X, FRAME, TMP, DATA, CNT
606) ;          Z (only for nested call)
607) ANIM_MOVIE_CODE:
608) ; get 4 bit code and 12 bit value
609)         lpm     DATA,Z+
610)         lpm     CNT,Z+
611)         mov     TMP,DATA
612)         andi    TMP,0xF0                ; 4 bit code (shifted left 4) is in TMP
613)         andi    DATA,0x0F               ; 12 bit value is in DATA:CNT
614) ; interpret code
615)         cpi     TMP,0x20
616)         brsh    ANIM_MOVIE_CODE_2_TO_F
617)         cpi     TMP,0x00
618)         breq    ANIM_MOVIE_CODE_0
619)         rjmp    ANIM_MOVIE_CODE_1
620) ANIM_MOVIE_CODE_2_TO_F:
621)         cpi     TMP,0x20
622)         breq    ANIM_MOVIE_CODE_2
623) ; unknown code -> end
624)         ldi     TMP,1                   ; end
625)         ret
626) 
627) ; plain frame
628) ANIM_MOVIE_CODE_0:
629) ; save 12 bit value
630)         push    DATA
631)         push    CNT
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

632) ; extract frame to frame buffer
633)         ldi     XL,low(FRAME)           ; ptr to pixel data
634)                                         ;   XH not there on ATtiny2313
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

635) ANIM_MOVIE_CODE_FRAME_PLAIN_LOOP:
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

636)         lpm     DATA,Z+                 ; get two pixels
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

637)         mov     TMP,DATA                ; write first pixel
638)         swap    TMP
639)         andi    TMP,0x0F
640)         st      X+,TMP
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

641)         andi    DATA,0x0F               ; write second pixel
642)         st      X+,DATA
643)         cpi     XL,low(FRAME)+42        ; bottom of loop
644)                                         ;   XH not there on ATtiny2313
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

645)         brlo    ANIM_MOVIE_CODE_FRAME_PLAIN_LOOP
646) ; restore 12 bit value
647)         pop     CNT
648)         pop     DATA
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

649) ; show frame
Stefan Schuermans movie compression, add anot...

Stefan Schuermans authored 5 years ago

650)         rjmp    ANIM_MOVIE_CODE_SHOW
651) 
652) ; rle frame
653) ANIM_MOVIE_CODE_1:
654) ; save 12 bit value
655)         push    DATA
656)         push    CNT
657) ; extract frame to frame buffer
658)         ldi     XL,low(FRAME)           ; ptr to pixel data
659)                                         ;   XH not there on ATtiny2313
660)         ldi     CNT,0                   ; no pixel data yet
661) ANIM_MOVIE_CODE_FRAME_RLE_LOOP:
662) ; load new pixel data if none available
663)         cpi     CNT,0
664)         brne    ANIM_MOVIE_CODE_FRAME_RLE_DATA_OK
665)         lpm     DATA,Z+                 ; get repeat count and pixel value
666)         mov     CNT,DATA
667)         andi    DATA,0x0F               ; pixel value in DATA
668)         swap    CNT
669)         andi    CNT,0x0F                ; repeat count in CNT
670)         inc     CNT                     ; use for repeat count + 1 pixels
671) ANIM_MOVIE_CODE_FRAME_RLE_DATA_OK:
672) ; write pixel data to frame
673)         st      X+,DATA
674) ; count down available pixel data
675)         dec     CNT
676) ; bottom of loop
677)         cpi     XL,low(FRAME)+42        ;   XH not there on ATtiny2313
678)         brlo    ANIM_MOVIE_CODE_FRAME_RLE_LOOP
679) ; restore 12 bit value
680)         pop     CNT
681)         pop     DATA
682) ; show frame
683)         rjmp    ANIM_MOVIE_CODE_SHOW
684) 
685) ; back reference
686) ANIM_MOVIE_CODE_2:
687) ; check if in nested call
688)         cpi     TMP2,0
689)         brne    ANIM_MOVIE_CODE_2_NESTED
690) ; save pointer to frame data
691)         push    ZL
692)         push    ZH
693) ; go back by 12 bit value in DATA:CNT
694)         sub     ZL,CNT
695)         sbc     ZH,DATA
696) ; recursive call
697)         ldi     TMP2,1                  ; nested call
698)         rcall   ANIM_MOVIE_CODE
699) ; restore pointer to frame data
700)         pop     ZH
701)         pop     ZL
702) ; done
703)         ldi     TMP,0                   ; continue
704)         ret
705) 
706) ; back reference - nested call
707) ANIM_MOVIE_CODE_2_NESTED:
708) ; go back by 12 bit value in DATA:CNT
709)         sub     ZL,CNT
710)         sbc     ZH,DATA
711) ; recursive tail call (no need to save Z on nested call)
712)         ldi     TMP2,1                  ; nested call
713)         rjmp    ANIM_MOVIE_CODE
714) 
715) ; show frame
716) ANIM_MOVIE_CODE_SHOW:
717) ; high part of frame time
718)         cpi     DATA,0
719)         breq    ANIM_MOVIE_CODE_SHOW_HIGH_DONE
720)         ldi     TMP,0                   ; means 256 frames times
721)         rcall   OUT_FRAME_TIME
722)         dec     DATA
723)         rjmp    ANIM_MOVIE_CODE_SHOW
724) ANIM_MOVIE_CODE_SHOW_HIGH_DONE:
725) ; low part of frame time
726)         cpi     CNT,0
727)         breq    ANIM_MOVIE_CODE_SHOW_LOW_DONE
728)         mov     TMP,CNT
729)         rcall   OUT_FRAME_TIME
730) ANIM_MOVIE_CODE_SHOW_LOW_DONE:
731) ; done
732)         ldi     TMP,0                   ; continue
733)         ret
734) 
735) 
736) 
737) ; play animation
738) ; input: Z = pointer to movie data
739) ; output: -
740) ; changes: X, Z, FRAME, CNT, DATA, TMP, TMP2
741) ANIM_MOVIE:
742) ; process code block
743)         ldi     TMP2,0                  ; initial call
744)         rcall   ANIM_MOVIE_CODE
745) ; continue if not yet end
746)         cpi     TMP,0
747)         breq    ANIM_MOVIE
748) ; done
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

749)         ret
750) 
751) 
752) 
753) .INCLUDE        "movie_funcs.inc"
754) 
755) 
756) 
Stefan Schuermans initial version of firmware

Stefan Schuermans authored 5 years ago

757) ; read mode from switch and (store animation number)
758) ; input: MODE = old mode, CNT = animation number
759) ; output: MODE = new mode
760) ; changes: TMP, DATA
761) MODE_READ:
762) ; read new mode (into DATA)
763)         ldi     DATA,MODE_ALL
764)         sbic    MODE_SW_PIN,MODE_SW_BIT
765)         ldi     DATA,MODE_SINGLE
766) ; mode was changed from all to single -> save animation number
767)         cpi     MODE,MODE_ALL           ; old mode not all -> do nothing
768)         brne    MODE_READ_NOT_0_TO_1
769)         cpi     DATA,MODE_SINGLE        ; new mode not single -> do nothing
770)         brne    MODE_READ_NOT_0_TO_1
771)         sbic    EECR,EEPE               ; EEPROM write ongoing -> do nothing
772)         rjmp    MODE_READ_NOT_0_TO_1
773)         ldi     TMP,0<<EEPM1|0<<EEPM0   ; set EEPROM programming mode
774)         out     EECR,TMP
775)         ldi     TMP,0                   ; set EEPROM address
776)         out     EEARL,TMP
777)         mov     TMP,CNT                 ; set EEPROM data to animation number
778)         com     TMP                     ;   with NOTed number in upper nibble
779)         swap    TMP
780)         andi    TMP,0xF0
781)         or      TMP,CNT
782)         out     EEDR,TMP
783)         sbi     EECR,EEMPE              ; begin writing EEPROM
784)         sbi     EECR,EEPE
785) MODE_READ_NOT_0_TO_1:
786) ; remember new mode (in MODE)
787)         mov     MODE,DATA
788) ; done
789)         ret
790) 
791) 
792) 
793) ; animation table: animation function, iteration count (<= 255)
794) ANIM_TAB:
Stefan Schuermans bbm2Chaosknoten

Stefan Schuermans authored 5 years ago

795) .INCLUDE        "movie_tab.inc"