2da19efe9ffa8f4ba42d32bd89c5339c369cfa13
[my-code/arm.git] / betty / display.c
1 /*
2  * display.c - handling the display
3  *
4  * author: hackbard@hackdaworld.org
5  *
6  */
7
8 /*
9  * some comments on alpha blending!
10  *
11  * ...
12  *
13  */
14
15 #include "display.h"
16 #include "system.h"
17 #include "default_logo.h"
18 #include "uart.h"
19
20 /*
21  * functions
22  */
23
24 void display_fill_screen(u8 fill) {
25
26         u8 page,width;
27         u8 buf[2];
28
29         buf[0]=0;
30         buf[1]=0;
31
32         switch(fill) {
33                 case DISPLAY_FILL_LG:
34                         buf[1]=0xff;
35                         break;
36                 case DISPLAY_FILL_DG:
37                         buf[0]=0xff;
38                         break;
39                 case DISPLAY_FILL_B:
40                         buf[0]=0xff;
41                         buf[1]=0xff;
42                         break;
43                 case DISPLAY_FILL_W:
44                 default:
45                         break;
46         }
47
48         for(page=0;page<DISPLAY_PAGE_MAX;page++) {
49                 DISPLAY_SET_C_ADDR(0);
50                 DISPLAY_SET_PAGE_ADDR(page);
51                 for(width=0;width<DISPLAY_DIMX;width++) {
52                         DISPLAY_DATA=buf[0];
53                         DISPLAY_DATA=buf[1];
54                 }
55         }
56 }
57
58 void display_clear_screen(void) {
59
60         display_fill_screen(DISPLAY_FILL_W);
61 }
62
63 void display_init(void) {
64
65         /* oscillator, regulator, boost, opamp, contrast */
66         DISPLAY_START_OSCILLATOR;
67         DISPLAY_SET_REGULATOR(7);
68         DISPLAY_SET_CONTRAST(0x38);
69         DISPLAY_SET_CONV_FACTOR(0x01);
70         DISPLAY_SET_POWER(DISPLAY_V_BOOST|DISPLAY_REGULATOR|DISPLAY_OPAMP);
71
72         // gray scale palette
73         DISPLAY_SET_WHITE(0,0,0,0);
74         DISPLAY_SET_LGRAY(5,5,5,5);     // obviously 3, but it's too bright!
75         DISPLAY_SET_DGRAY(7,7,7,7);     // obviously 6, but again too bright!
76         DISPLAY_SET_BLACK(9,9,9,9);
77
78         /* normal mode, display depending ram content */
79         DISPLAY_RAM_CONTENTS_ON;
80         display_clear_screen();
81         DISPLAY_NORMAL;                 // 00 -> white, 11 -> black
82         DISPLAY_SET_COM_ODIR_REMAPPED;  // start counting at the top
83
84         /* switch on the display */
85         DISPLAY_SET_ON;
86 }
87
88 void display_load_logo(u8 *src) {
89
90         u8 *s;
91         u8 page,width;
92
93         s=src;
94         if(s==0)
95                 s=default_logo;
96
97         for(page=0;page<DISPLAY_PAGE_MAX;page++) {
98                 DISPLAY_SET_C_ADDR(0);
99                 DISPLAY_SET_PAGE_ADDR(page);
100                 for(width=0;width<DISPLAY_DIMX;width++) {
101                         DISPLAY_DATA=*s++;
102                         DISPLAY_DATA=*s++;
103                 }
104         }
105 }
106
107 void display_draw_rectangle(int x,int y,int w,int h,u8 fill,u8 alpha) {
108
109         int c,r,rmax;
110         u8 p,spage,epage;
111         u8 b[2],a[2];           // c = a over b => c=alpha*a+(1-alpha)*b
112
113         a[0]=0;
114         a[1]=0;
115         switch(fill) {
116                 case DISPLAY_FILL_LG:
117                         a[1]=1;
118                         break;
119                 case DISPLAY_FILL_DG:
120                         a[0]=1;
121                         break;
122                 case DISPLAY_FILL_B:
123                         a[0]=1;
124                         a[1]=1;
125                 case DISPLAY_FILL_W:
126                 default:
127                         break;
128         }
129
130         spage=y>>3;                                     // start page = y/8
131         epage=(y+h)>>3;                                 // end page (y+h)/8
132
133         for(p=spage;p<=epage;p++) {
134                 DISPLAY_SET_PAGE_ADDR(p);
135                 for(c=x;c<x+w;c++) {
136                         DISPLAY_SET_C_ADDR(c);
137                         b[0]=DISPLAY_DATA;              // dummy read (p.16)
138                         b[0]=DISPLAY_DATA;
139                         b[1]=DISPLAY_DATA;
140                         rmax=y+8>y+h?y+h:y+8;
141                         for(r=y;r<rmax;r++) {
142                                 b[0]&=~(1<<r);
143                                 b[1]&=~(1<<r);
144                                 b[0]|=a[0]<<r;
145                                 b[1]|=a[1]<<r;
146                         }
147                         DISPLAY_SET_C_ADDR(c);
148                         DISPLAY_DATA=b[0];
149                         DISPLAY_DATA=b[1];
150                 }
151                 y+=8;
152         }
153 }
154
155 void display_bl_init(void) {
156
157         IODIR0|=(1<<4);
158         IOSET0=(1<<4);  // off by default
159 }
160
161 void display_bl_toggle(void) {
162
163         if(IOPIN0&(1<<4))
164                 IOCLR0=(1<<4);
165         else
166                 IOSET0=(1<<4);
167 }
168
169 void display_bl_on(void) {
170
171         IOCLR0=(1<<4);
172 }
173
174 void display_bl_off(void) {
175
176         IOSET0=(1<<4);
177 }
178