2 * Creation Date: <2002/10/23 20:26:40 samuel>
3 * Time-stamp: <2004/01/07 19:39:15 samuel>
7 * Mac-on-Linux display node
9 * Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation
18 #include "libopenbios/bindings.h"
19 #include "libc/diskio.h"
20 #include "libopenbios/ofmem.h"
21 #include "drivers/drivers.h"
22 #include "packages/video.h"
23 #include "libopenbios/console.h"
24 #include "drivers/vga.h"
26 typedef struct osi_fb_info
{
34 unsigned long *pal
; /* 256 elements */
39 video_get_res( int *w
, int *h
)
41 if( !video
.has_video
) {
51 startup_splash( void )
54 int fd
, s
, i
, y
, x
, dx
, dy
;
60 /* only draw logo in 24-bit mode (for now) */
61 if( video
.fb
.depth
< 15 )
64 for( i
=0; i
<2; i
++ ) {
65 if( !BootHGetStrResInd("bootlogo", buf
, sizeof(buf
), 0, i
) )
67 *(!i
? &width
: &height
) = atol(buf
);
70 if( (s
=width
* height
* 3) > 0x20000 )
73 if( (fd
=open_io("pseudo:,bootlogo")) >= 0 ) {
75 if( read_io(fd
, p
, s
) != s
)
76 printk("bootlogo size error\n");
79 dx
= (video
.fb
.w
- width
)/2;
80 dy
= (video
.fb
.h
- height
)/3;
82 pp
= (char*)video
.fb
.mphys
+ dy
* video
.fb
.rb
+ dx
* (video
.fb
.depth
>= 24 ? 4 : 2);
84 for( y
=0 ; y
<height
; y
++, pp
+= video
.fb
.rb
) {
85 if( video
.fb
.depth
>= 24 ) {
86 unsigned long *d
= (unsigned long*)pp
;
87 for( x
=0; x
<width
; x
++, p
+=3, d
++ )
88 *d
= ((int)p
[0] << 16) | ((int)p
[1] << 8) | p
[2];
89 } else if( video
.fb
.depth
== 15 ) {
90 unsigned short *d
= (unsigned short*)pp
;
91 for( x
=0; x
<width
; x
++, p
+=3, d
++ ) {
92 int col
= ((int)p
[0] << 16) | ((int)p
[1] << 8) | p
[2];
93 *d
= ((col
>>9) & 0x7c00) | ((col
>>6) & 0x03e0) | ((col
>>3) & 0x1f);
100 /* No bootlogo support yet on other platforms */
106 get_color( int col_ind
)
109 if( !video
.has_video
|| col_ind
< 0 || col_ind
> 255 )
111 if( video
.fb
.depth
== 8 )
113 col
= video
.pal
[col_ind
];
114 if( video
.fb
.depth
== 24 || video
.fb
.depth
== 32 )
116 if( video
.fb
.depth
== 15 )
117 return ((col
>>9) & 0x7c00) | ((col
>>6) & 0x03e0) | ((col
>>3) & 0x1f);
122 draw_pixel( int x
, int y
, int colind
)
124 char *p
= (char*)video
.fb
.mphys
+ video
.fb
.rb
* y
;
125 int color
, d
= video
.fb
.depth
;
127 if( x
< 0 || y
< 0 || x
>= video
.fb
.w
|| y
>=video
.fb
.h
)
129 color
= get_color( colind
);
132 *((unsigned long*)p
+ x
) = color
;
134 *((short*)p
+ x
) = color
;
140 fill_rect( int col_ind
, int x
, int y
, int w
, int h
)
143 unsigned long col
= get_color(col_ind
);
145 if (!video
.has_video
|| x
< 0 || y
< 0 || w
<= 0 || h
<= 0 ||
146 x
+ w
> video
.fb
.w
|| y
+ h
> video
.fb
.h
)
149 pp
= (char*)video
.fb
.mphys
+ video
.fb
.rb
* y
;
150 for( ; h
--; pp
+= video
.fb
.rb
) {
152 if( video
.fb
.depth
== 24 || video
.fb
.depth
== 32 ) {
153 unsigned long *p
= (unsigned long*)pp
+ x
;
156 } else if( video
.fb
.depth
== 16 || video
.fb
.depth
== 15 ) {
157 unsigned short *p
= (unsigned short*)pp
+ x
;
161 char *p
= (char *)((unsigned short*)pp
+ x
);
170 refresh_palette( void )
173 if( video
.fb
.depth
== 8 )
174 OSI_RefreshPalette();
179 set_color( int ind
, unsigned long color
)
181 if( !video
.has_video
|| ind
< 0 || ind
> 255 )
183 video
.pal
[ind
] = color
;
186 if( video
.fb
.depth
== 8 )
187 OSI_SetColor( ind
, color
);
188 #elif defined(CONFIG_SPARC32)
189 if( video
.fb
.depth
== 8 ) {
191 dac
[1] = ((color
>> 16) & 0xff) << 24; // Red
192 dac
[1] = ((color
>> 8) & 0xff) << 24; // Green
193 dac
[1] = (color
& 0xff) << 24; // Blue
196 vga_set_color(ind
, ((color
>> 16) & 0xff),
197 ((color
>> 8) & 0xff),
203 video_scroll( int height
)
205 int i
, offs
, size
, *dest
, *src
;
207 if (height
<= 0 || height
>= video
.fb
.h
) {
210 offs
= video
.fb
.rb
* height
;
211 size
= (video
.fb
.h
* video
.fb
.rb
- offs
)/16;
212 dest
= (int*)video
.fb
.mphys
;
213 src
= (int*)(video
.fb
.mphys
+ offs
);
215 for( i
=0; i
<size
; i
++ ) {
225 /************************************************************************/
227 /************************************************************************/
229 DECLARE_NODE( video
, INSTALL_OPEN
, 0, "Tdisplay" );
231 /* ( -- width height ) (?) */
233 video_dimensions( void )
236 (void) video_get_res( &w
, &h
);
241 /* ( table start count -- ) (?) */
243 video_set_colors( void )
247 unsigned char *p
= (unsigned char*)cell2pointer(POP());
250 for( i
=0; i
<count
; i
++, p
+=3 ) {
251 unsigned long col
= (p
[0] << 16) | (p
[1] << 8) | p
[2];
252 set_color( i
+ start
, col
);
257 /* ( r g b index -- ) */
259 video_color_bang( void )
265 unsigned long col
= ((r
<< 16) & 0xff0000) | ((g
<< 8) & 0x00ff00) | (b
& 0xff);
266 /* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */
267 set_color( index
, col
);
271 /* ( color_ind x y width height -- ) (?) */
273 video_fill_rect( void )
279 int color_ind
= POP();
281 fill_rect( color_ind
, x
, y
, w
, h
);
284 /* ( addr len -- actual ) */
292 addr
= (char *)cell2pointer(POP());
294 console_draw_fstr(addr
, len
);
298 NODE_METHODS( video
) = {
299 {"dimensions", video_dimensions
},
300 {"set-colors", video_set_colors
},
301 {"fill-rectangle", video_fill_rect
},
302 {"color!", video_color_bang
},
303 {"write", video_write
},
307 /************************************************************************/
309 /************************************************************************/
312 init_video( unsigned long fb
, int width
, int height
, int depth
, int rb
)
323 video
.fb
.depth
= depth
;
325 while( (ph
=dt_iterate_type(ph
, "display")) ) {
326 set_int_property( ph
, "width", video
.fb
.w
);
327 set_int_property( ph
, "height", video
.fb
.h
);
328 set_int_property( ph
, "depth", video
.fb
.depth
);
329 set_int_property( ph
, "linebytes", video
.fb
.rb
);
330 set_int_property( ph
, "address", video
.fb
.mphys
);
333 video
.pal
= malloc( 256 * sizeof(unsigned long) );
336 s
= (video
.fb
.mphys
& 0xfff);
337 size
= ((video
.fb
.h
* video
.fb
.rb
+ s
) + 0xfff) & ~0xfff;
339 ofmem_claim_phys( video
.fb
.mphys
, size
, 0 );
340 ofmem_claim_virt( video
.fb
.mphys
, size
, 0 );
341 ofmem_map( video
.fb
.mphys
, video
.fb
.mphys
, size
, -1 );
344 for( i
=0; i
<256; i
++ )
345 set_color( i
, i
* 0x010101 );
347 set_color( 254, 0xffffcc );
348 fill_rect( 254, 0, 0, video
.fb
.w
, video
.fb
.h
);
353 REGISTER_NODE( video
);