~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/fbcon-afb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/drivers/video/afb.c -- Low level frame buffer operations for
  3  *                               bitplanes à la Amiga
  4  *
  5  *      Created 5 Apr 1997 by Geert Uytterhoeven
  6  *
  7  *  This file is subject to the terms and conditions of the GNU General Public
  8  *  License.  See the file COPYING in the main directory of this archive for
  9  *  more details.
 10  */
 11 
 12 #include <linux/module.h>
 13 #include <linux/tty.h>
 14 #include <linux/console.h>
 15 #include <linux/string.h>
 16 #include <linux/fb.h>
 17 
 18 #include <video/fbcon.h>
 19 #include <video/fbcon-afb.h>
 20 
 21 
 22     /*
 23      *  Bitplanes à la Amiga
 24      */
 25 
 26 static u8 expand_table[1024] = {
 27     /*  bg = fg = 0 */
 28     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 29     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 30     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 31     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 32     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 33     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 34     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 35     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 36     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 37     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 38     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 39     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 40     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 41     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 42     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 43     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 44     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 45     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 46     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 47     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 48     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 49     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 50     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 51     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 52     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 53     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 54     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 55     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 56     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 57     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 58     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 59     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 60     /* bg = 0, fg = 1 */
 61     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 62     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 63     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
 64     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 65     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
 66     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 67     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
 68     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 69     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 70     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 71     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
 72     0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 73     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
 74     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 75     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
 76     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 77     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
 78     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 79     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 80     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 81     0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 82     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 83     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 84     0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 85     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 86     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 87     0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 88     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 89     0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 90     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 91     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 92     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 93     /* bg = 1, fg = 0 */
 94     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
 95     0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
 96     0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
 97     0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
 98     0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
 99     0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
100     0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
101     0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
102     0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
103     0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
104     0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
105     0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
106     0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
107     0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
108     0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
109     0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
110     0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
111     0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
112     0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
113     0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
114     0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
115     0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
116     0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
117     0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
118     0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
119     0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
120     0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
121     0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
122     0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
123     0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
124     0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
125     0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
126     /* bg = fg = 1 */
127     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
128     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
129     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
130     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
132     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
133     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
136     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
137     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
138     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
139     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
140     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
141     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
142     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
143     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
144     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
145     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
148     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
150     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
156     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
158     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
159 };
160 
161 void fbcon_afb_setup(struct display *p)
162 {
163     if (p->line_length)
164         p->next_line = p->line_length;
165     else
166         p->next_line = p->var.xres_virtual>>3;
167     p->next_plane = p->var.yres_virtual*p->next_line;
168 }
169 
170 void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
171                      int height, int width)
172 {
173     u8 *src, *dest, *src0, *dest0;
174     u_short i, j;
175 
176     if (sx == 0 && dx == 0 && width == p->next_line) {
177         src = p->screen_base+sy*fontheight(p)*width;
178         dest = p->screen_base+dy*fontheight(p)*width;
179         i = p->var.bits_per_pixel;
180         do {
181             fb_memmove(dest, src, height*fontheight(p)*width);
182             src += p->next_plane;
183             dest += p->next_plane;
184         } while (--i);
185     } else if (dy <= sy) {
186         src0 = p->screen_base+sy*fontheight(p)*p->next_line+sx;
187         dest0 = p->screen_base+dy*fontheight(p)*p->next_line+dx;
188         i = p->var.bits_per_pixel;
189         do {
190             src = src0;
191             dest = dest0;
192             j = height*fontheight(p);
193             do {
194                 fb_memmove(dest, src, width);
195                 src += p->next_line;
196                 dest += p->next_line;
197             } while (--j);
198             src0 += p->next_plane;
199             dest0 += p->next_plane;
200         } while (--i);
201     } else {
202         src0 = p->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
203         dest0 = p->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
204         i = p->var.bits_per_pixel;
205         do {
206             src = src0;
207             dest = dest0;
208             j = height*fontheight(p);
209             do {
210                 src -= p->next_line;
211                 dest -= p->next_line;
212                 fb_memmove(dest, src, width);
213             } while (--j);
214             src0 += p->next_plane;
215             dest0 += p->next_plane;
216         } while (--i);
217     }
218 }
219 
220 void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
221                      int height, int width)
222 {
223     u8 *dest, *dest0;
224     u_short i, j;
225     int bg;
226 
227     dest0 = p->screen_base+sy*fontheight(p)*p->next_line+sx;
228 
229     bg = attr_bgcol_ec(p,conp);
230     i = p->var.bits_per_pixel;
231     do {
232         dest = dest0;
233         j = height*fontheight(p);
234         do {
235             if (bg & 1)
236                 fb_memset255(dest, width);
237             else
238                 fb_memclear(dest, width);
239             dest += p->next_line;
240         } while (--j);
241         bg >>= 1;
242         dest0 += p->next_plane;
243     } while (--i);
244 }
245 
246 void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
247                     int xx)
248 {
249     u8 *dest, *dest0, *cdat, *cdat0, *expand;
250     u_short i, j;
251     int fg, bg;
252 
253     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
254     cdat0 = p->fontdata+(c&p->charmask)*fontheight(p);
255     fg = attr_fgcol(p,c);
256     bg = attr_bgcol(p,c);
257 
258     i = p->var.bits_per_pixel;
259     do {
260         dest = dest0;
261         cdat = cdat0;
262         expand = expand_table;
263         if (bg & 1)
264             expand += 512;
265         if (fg & 1)
266             expand += 256;
267         j = fontheight(p);
268         do {
269             *dest = expand[*cdat++];
270             dest += p->next_line;
271         } while (--j);
272         bg >>= 1;
273         fg >>= 1;
274         dest0 += p->next_plane;
275     } while (--i);
276 }
277 
278     /*
279      *  I've split the console character loop in two parts
280      *  (cfr. fbcon_putcs_ilbm())
281      */
282 
283 void fbcon_afb_putcs(struct vc_data *conp, struct display *p, 
284                      const unsigned short *s, int count, int yy, int xx)
285 {
286     u8 *dest, *dest0, *dest1, *expand;
287     u8 *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
288     u_short i, j;
289     u16 c1, c2, c3, c4;
290     int fg0, bg0, fg, bg;
291 
292     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
293     fg0 = attr_fgcol(p, scr_readw(s));
294     bg0 = attr_bgcol(p, scr_readw(s));
295 
296     while (count--)
297         if (xx&3 || count < 3) {        /* Slow version */
298             c1 = scr_readw(s++) & p->charmask;
299             dest1 = dest0++;
300             xx++;
301 
302             cdat10 = p->fontdata+c1*fontheight(p);
303             fg = fg0;
304             bg = bg0;
305 
306             i = p->var.bits_per_pixel;
307             do {
308                 dest = dest1;
309                 cdat1 = cdat10;
310                 expand = expand_table;
311                 if (bg & 1)
312                     expand += 512;
313                 if (fg & 1)
314                     expand += 256;
315                 j = fontheight(p);
316                 do {
317                     *dest = expand[*cdat1++];
318                     dest += p->next_line;
319                 } while (--j);
320                 bg >>= 1;
321                 fg >>= 1;
322                 dest1 += p->next_plane;
323             } while (--i);
324         } else {                        /* Fast version */
325             c1 = scr_readw(&s[0]) & p->charmask;
326             c2 = scr_readw(&s[1]) & p->charmask;
327             c3 = scr_readw(&s[2]) & p->charmask;
328             c4 = scr_readw(&s[3]) & p->charmask;
329 
330             dest1 = dest0;
331             cdat10 = p->fontdata+c1*fontheight(p);
332             cdat20 = p->fontdata+c2*fontheight(p);
333             cdat30 = p->fontdata+c3*fontheight(p);
334             cdat40 = p->fontdata+c4*fontheight(p);
335             fg = fg0;
336             bg = bg0;
337 
338             i = p->var.bits_per_pixel;
339             do {
340                 dest = dest1;
341                 cdat1 = cdat10;
342                 cdat2 = cdat20;
343                 cdat3 = cdat30;
344                 cdat4 = cdat40;
345                 expand = expand_table;
346                 if (bg & 1)
347                     expand += 512;
348                 if (fg & 1)
349                     expand += 256;
350                 j = fontheight(p);
351                 do {
352 #if defined(__BIG_ENDIAN)
353                     *(u32 *)dest = expand[*cdat1++]<<24 |
354                                    expand[*cdat2++]<<16 |
355                                    expand[*cdat3++]<<8 |
356                                    expand[*cdat4++];
357 #elif defined(__LITTLE_ENDIAN)
358                     *(u32 *)dest = expand[*cdat1++] |
359                                    expand[*cdat2++]<<8 |
360                                    expand[*cdat3++]<<16 |
361                                    expand[*cdat4++]<<24;
362 #else
363 #error FIXME: No endianness??
364 #endif
365                     dest += p->next_line;
366                 } while (--j);
367                 bg >>= 1;
368                 fg >>= 1;
369                 dest1 += p->next_plane;
370             } while (--i);
371             s += 4;
372             dest0 += 4;
373             xx += 4;
374             count -= 3;
375         }
376 }
377 
378 void fbcon_afb_revc(struct display *p, int xx, int yy)
379 {
380     u8 *dest, *dest0;
381     u_short i, j;
382     int mask;
383 
384     dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
385     mask = p->fgcol ^ p->bgcol;
386 
387     /*
388      *  This should really obey the individual character's
389      *  background and foreground colors instead of simply
390      *  inverting.
391      */
392 
393     i = p->var.bits_per_pixel;
394     do {
395         if (mask & 1) {
396             dest = dest0;
397             j = fontheight(p);
398             do {
399                 *dest = ~*dest;
400                 dest += p->next_line;
401             } while (--j);
402         }
403         mask >>= 1;
404         dest0 += p->next_plane;
405     } while (--i);
406 }
407 
408 
409     /*
410      *  `switch' for the low level operations
411      */
412 
413 struct display_switch fbcon_afb = {
414     setup:              fbcon_afb_setup,
415     bmove:              fbcon_afb_bmove,
416     clear:              fbcon_afb_clear,
417     putc:               fbcon_afb_putc,
418     putcs:              fbcon_afb_putcs,
419     revc:               fbcon_afb_revc,
420     fontwidthmask:      FONTWIDTH(8)
421 };
422 
423 
424 #ifdef MODULE
425 int init_module(void)
426 {
427     return 0;
428 }
429 
430 void cleanup_module(void)
431 {}
432 #endif /* MODULE */
433 
434 
435     /*
436      *  Visible symbols for modules
437      */
438 
439 EXPORT_SYMBOL(fbcon_afb);
440 EXPORT_SYMBOL(fbcon_afb_setup);
441 EXPORT_SYMBOL(fbcon_afb_bmove);
442 EXPORT_SYMBOL(fbcon_afb_clear);
443 EXPORT_SYMBOL(fbcon_afb_putc);
444 EXPORT_SYMBOL(fbcon_afb_putcs);
445 EXPORT_SYMBOL(fbcon_afb_revc);
446 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.