2 * Creation Date: <2002/10/23 20:26:40 samuel>
3 * Time-stamp: <2004/01/07 19:39:15 samuel>
7 * Shared video routines
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 "libc/vsprintf.h"
19 #include "libopenbios/bindings.h"
20 #include "libopenbios/fontdata.h"
21 #include "libopenbios/ofmem.h"
22 #include "libopenbios/video.h"
23 #include "packages/video.h"
24 #include "drivers/vga.h"
25 #define NO_QEMU_PROTOS
26 #include "arch/common/fw_cfg.h"
28 struct video_info video;
31 video_get_color( int col_ind )
34 if( !VIDEO_DICT_VALUE(video.ih) || col_ind < 0 || col_ind > 255 )
36 if( VIDEO_DICT_VALUE(video.depth) == 8 )
38 col = video.pal[col_ind];
39 if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 )
41 if( VIDEO_DICT_VALUE(video.depth) == 15 )
42 return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
46 /* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */
51 ucell bgcolor = POP();
52 ucell fgcolor = POP();
55 unsigned char *mask = (unsigned char *)POP();
56 unsigned char *fbaddr = (unsigned char *)POP();
59 unsigned char *dst, *rowdst;
60 int x, y, m, b, d, depthbytes;
62 fgcolor = video_get_color(fgcolor);
63 bgcolor = video_get_color(bgcolor);
64 d = VIDEO_DICT_VALUE(video.depth);
65 depthbytes = (d + 1) >> 3;
68 for( y = 0; y < height; y++) {
70 for( x = 0; x < (width + 1) >> 3; x++ ) {
71 for (b = 0; b < 8; b++) {
81 *((uint32_t*)dst) = color;
83 *((uint16_t*)dst) = color;
92 dst += VIDEO_DICT_VALUE(video.rb);
96 /* ( x y w h fgcolor bgcolor -- ) */
99 video_invert_rect( void )
101 ucell bgcolor = POP();
102 ucell fgcolor = POP();
109 bgcolor = video_get_color(bgcolor);
110 fgcolor = video_get_color(fgcolor);
112 if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 ||
113 x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h))
116 pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y;
117 for( ; h--; pp += *(video.rb) ) {
119 if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) {
120 uint32_t *p = (uint32_t*)pp + x;
124 } else if (*p == bgcolor) {
128 } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) {
129 uint16_t *p = (uint16_t*)pp + x;
131 if (*p == (uint16_t)fgcolor) {
133 } else if (*p == (uint16_t)bgcolor) {
138 char *p = (char *)(pp + x);
141 if (*p == (char)fgcolor) {
143 } else if (*p == (char)bgcolor) {
151 /* ( color_ind x y width height -- ) (?) */
153 video_fill_rect(void)
162 unsigned long col = video_get_color(col_ind);
164 if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 ||
165 x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h))
168 pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y;
169 for( ; h--; pp += VIDEO_DICT_VALUE(video.rb) ) {
171 if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) {
172 uint32_t *p = (uint32_t*)pp + x;
175 } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) {
176 uint16_t *p = (uint16_t*)pp + x;
180 char *p = (char *)(pp + x);
190 /* Make everything inside the video_info structure point to the
191 values in the Forth dictionary. Hence everything is always in
196 feval("['] display-ih cell+");
197 video.ih = cell2pointer(POP());
199 feval("['] frame-buffer-adr cell+");
200 video.mvirt = cell2pointer(POP());
201 feval("['] openbios-video-width cell+");
202 video.w = cell2pointer(POP());
203 feval("['] openbios-video-height cell+");
204 video.h = cell2pointer(POP());
205 feval("['] depth-bits cell+");
206 video.depth = cell2pointer(POP());
207 feval("['] line-bytes cell+");
208 video.rb = cell2pointer(POP());
209 feval("['] color-palette cell+");
210 video.pal = cell2pointer(POP());
212 /* Set global variables ready for fb8-install */
213 PUSH( pointer2cell(video_mask_blit) );
214 fword("is-noname-cfunc");
215 feval("to fb8-blitmask");
216 PUSH( pointer2cell(video_fill_rect) );
217 fword("is-noname-cfunc");
218 feval("to fb8-fillrect");
219 PUSH( pointer2cell(video_invert_rect) );
220 fword("is-noname-cfunc");
221 feval("to fb8-invertrect");
223 /* Static information */
224 PUSH((ucell)fontdata);
225 feval("to (romfont)");
227 feval("to (romfont-height)");
229 feval("to (romfont-width)");
231 /* Initialise the structure */
232 VIDEO_DICT_VALUE(video.w) = VGA_DEFAULT_WIDTH;
233 VIDEO_DICT_VALUE(video.h) = VGA_DEFAULT_HEIGHT;
234 VIDEO_DICT_VALUE(video.depth) = VGA_DEFAULT_DEPTH;
235 VIDEO_DICT_VALUE(video.rb) = VGA_DEFAULT_LINEBYTES;
237 #if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64))
238 /* If running from QEMU, grab the parameters from the firmware interface */
241 w = fw_cfg_read_i16(FW_CFG_ARCH_WIDTH);
242 h = fw_cfg_read_i16(FW_CFG_ARCH_HEIGHT);
243 d = fw_cfg_read_i16(FW_CFG_ARCH_DEPTH);
245 VIDEO_DICT_VALUE(video.w) = w;
246 VIDEO_DICT_VALUE(video.h) = h;
247 VIDEO_DICT_VALUE(video.depth) = d;
248 VIDEO_DICT_VALUE(video.rb) = (w * ((d + 7) / 8));
252 /* Setup screen-#rows/screen-#columns */
253 options = find_dev("/options");
254 snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.w) / FONT_WIDTH);
255 set_property(options, "screen-#columns", buf, strlen(buf) + 1);
256 snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.h) / FONT_HEIGHT);
257 set_property(options, "screen-#rows", buf, strlen(buf) + 1);