Instead if having a large #ifdef .. #endif section in video_set_color(), move the device-specific hardware setters into each display device package.
To do this, we keep track of the display ihandle in the video structure and use it to invoke the low-level hardware setter routine (and optional palette refresh) if required.
Also since the display-ih isn't called until is-install, defer the colour palette initialisation from init_video() to is-install.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/console.c | 17 ++++++++++ openbios-devel/drivers/sbus.c | 1 + openbios-devel/drivers/vga_vbe.c | 18 +++++++++++ openbios-devel/forth/device/display.fs | 25 +++++++++++++++ openbios-devel/include/drivers/drivers.h | 1 + openbios-devel/include/libopenbios/video.h | 1 + openbios-devel/libopenbios/video_common.c | 46 ++++++++++++++-------------- openbios-devel/packages/molvideo.c | 19 +++++++++--- 8 files changed, 101 insertions(+), 27 deletions(-)
diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c index c986e2b..53aa77f 100644 --- a/openbios-devel/arch/sparc32/console.c +++ b/openbios-devel/arch/sparc32/console.c @@ -11,6 +11,7 @@ #include "openbios.h" #include "libopenbios/console.h" #include "libopenbios/ofmem.h" +#include "libopenbios/video.h"
void cls(void);
@@ -41,6 +42,22 @@ void tcx_init(uint64_t base) dac = (uint32_t *)ofmem_map_io(base + DAC_BASE, DAC_SIZE); }
+/* ( r g b index -- ) */ +void tcx_hw_set_color(void) +{ + int index = POP(); + int b = POP(); + int g = POP(); + int r = POP(); + + if( VIDEO_DICT_VALUE(video.depth) == 8 ) { + dac[0] = index << 24; + dac[1] = r << 24; // Red + dac[1] = g << 24; // Green + dac[1] = b << 24; // Blue + } +} + #endif
/* ****************************************************************** diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c index d171018..fbac2d7 100644 --- a/openbios-devel/drivers/sbus.c +++ b/openbios-devel/drivers/sbus.c @@ -329,6 +329,7 @@ ob_tcx_init(unsigned int slot, const char *path) fword("property"); }
+ bind_func("hw-set-color", tcx_hw_set_color); feval("['] qemu-tcx-driver-init is-install");
chosen = find_dev("/chosen"); diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 884c261..33765b6 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -103,6 +103,22 @@ void vga_vbe_set_mode(int width, int height, int depth) vga_build_rgb_palette(); }
+/* Low-level Forth accessor to update VGA color registers */ + +/* ( r g b index -- ) */ +static +void vga_hw_set_color(void) +{ + int index = POP(); + int b = POP(); + int g = POP(); + int r = POP(); + + vga_set_color(index, (r & 0xff), + (g & 0xff), + (b & 0xff)); +} + void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, unsigned long rom, uint32_t rom_size) { @@ -128,6 +144,8 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, ph = get_cur_dev(); #endif
+ bind_func("hw-set-color", vga_hw_set_color); + set_int_property(ph, "width", VIDEO_DICT_VALUE(video.w)); set_int_property(ph, "height", VIDEO_DICT_VALUE(video.h)); set_int_property(ph, "depth", VIDEO_DICT_VALUE(video.depth)); diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index cf709fa..ae7bdeb 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -48,6 +48,7 @@ create color-palette 100 cells allot 2 value font-spacing 0 value depth-bits 0 value line-bytes +0 value display-ih
\ internal values read from QEMU firmware interface 0 value qemu-video-addr @@ -353,6 +354,8 @@ defer fb8-invertrect 0 to inverse? 0 to inverse-screen?
+ my-self to display-ih + \ set defer functions to 8bit versions
['] fb8-draw-character to draw-character @@ -375,6 +378,28 @@ defer fb8-invertrect then to foreground-color to background-color
+ \ setup palette + 10101 ['] color-palette cell+ ff 0 do + dup 2 pick i * swap ! cell+ + loop 2drop + + \ special background color + ffffcc ['] color-palette cell+ fe cells + ! + + \ load palette onto the hardware + ['] color-palette cell+ ff 0 do + dup @ ff0000 and d# 16 rshift + 1 pick @ ff00 and d# 8 rshift + 2 pick @ ff and + i + s" hw-set-color" $find if + execute + else + 2drop + then + cell+ + loop drop + \ ... but let's override with some better defaults fe to background-color 0 to foreground-color diff --git a/openbios-devel/include/drivers/drivers.h b/openbios-devel/include/drivers/drivers.h index d139ace..d041e81 100644 --- a/openbios-devel/include/drivers/drivers.h +++ b/openbios-devel/include/drivers/drivers.h @@ -47,6 +47,7 @@ int ob_sbus_init(uint64_t base, int machine_id);
/* arch/sparc32/console.c */ void tcx_init(uint64_t base); +void tcx_hw_set_color(void); void kbd_init(uint64_t base); #endif #ifdef CONFIG_DRIVER_IDE diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index bcd024e..cf2b5db 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -30,6 +30,7 @@ void video_fill_rect(void); extern struct video_info { int has_video;
+ volatile ihandle_t *ih; volatile phys_addr_t mphys; volatile ucell *mvirt; volatile ucell *rb, *w, *h, *depth; diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 9d45e69..ca2826e 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -46,27 +46,30 @@ video_get_color( int col_ind ) void video_set_color( int ind, unsigned long color ) { + xt_t hw_xt = 0; + if( !video.has_video || ind < 0 || ind > 255 ) return; video.pal[ind] = color;
-#ifdef CONFIG_MOL - if( VIDEO_DICT_VALUE(video.depth) == 8 ) - OSI_SetColor( ind, color ); -#elif defined(CONFIG_SPARC32) -#if defined(CONFIG_DEBUG_CONSOLE_VIDEO) - if( VIDEO_DICT_VALUE(video.depth) == 8 ) { - dac[0] = ind << 24; - dac[1] = ((color >> 16) & 0xff) << 24; // Red - dac[1] = ((color >> 8) & 0xff) << 24; // Green - dac[1] = (color & 0xff) << 24; // Blue - } -#endif -#else - vga_set_color(ind, ((color >> 16) & 0xff), - ((color >> 8) & 0xff), - (color & 0xff)); -#endif + /* Call the low-level hardware setter in the + display package */ + hw_xt = find_ih_method("hw-set-color", VIDEO_DICT_VALUE(video.ih)); + if (hw_xt) { + PUSH((color >> 16) & 0xff); // Red + PUSH((color >> 8) & 0xff); // Green + PUSH(color & 0xff); // Blue + PUSH(ind); + PUSH(hw_xt); + fword("execute"); + } + + /* Call the low-level palette update if required */ + hw_xt = find_ih_method("hw-refresh-palette", VIDEO_DICT_VALUE(video.ih)); + if (hw_xt) { + PUSH(hw_xt); + fword("execute"); + } }
/* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */ @@ -219,6 +222,9 @@ void setup_video(phys_addr_t phys, ucell virt)
video.mphys = phys;
+ feval("['] display-ih cell+"); + video.ih = cell2pointer(POP()); + feval("['] qemu-video-addr cell+"); video.mvirt = cell2pointer(POP()); feval("['] qemu-video-width cell+"); @@ -277,7 +283,6 @@ void setup_video(phys_addr_t phys, ucell virt) void init_video(void) { - int i; #if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) int size; #endif @@ -306,9 +311,4 @@ init_video(void) ofmem_claim_virt( VIDEO_DICT_VALUE(video.mvirt), size, 0 ); ofmem_map( video.mphys, VIDEO_DICT_VALUE(video.mvirt), size, ofmem_arch_io_translation_mode(video.mphys) ); #endif - - for( i=0; i<256; i++ ) - video_set_color( i, i * 0x010101 ); - - video_set_color( 254, 0xffffcc ); } diff --git a/openbios-devel/packages/molvideo.c b/openbios-devel/packages/molvideo.c index 742f516..24cc2fd 100644 --- a/openbios-devel/packages/molvideo.c +++ b/openbios-devel/packages/molvideo.c @@ -31,15 +31,24 @@
DECLARE_NODE( video, 0, 0, "Tdisplay" );
+#ifdef CONFIG_MOL static void molvideo_refresh_palette( void ) { -#ifdef CONFIG_MOL + if( VIDEO_DICT_VALUE(video.depth) == 8 ) OSI_RefreshPalette(); -#endif }
+static void +molvideo_hw_set_color( void ) +{ + + if( VIDEO_DICT_VALUE(video.depth) == 8 ) + OSI_SetColor( ind, color ); +} +#endif + /* ( -- width height ) (?) */ static void molvideo_dimensions( void ) @@ -61,7 +70,6 @@ molvideo_set_colors( void ) unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2]; video_set_color( i + start, col ); } - molvideo_refresh_palette(); }
/* ( r g b index -- ) */ @@ -75,7 +83,6 @@ molvideo_color_bang( void ) unsigned long col = ((r << 16) & 0xff0000) | ((g << 8) & 0x00ff00) | (b & 0xff); /* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */ video_set_color( index, col ); - molvideo_refresh_palette(); }
/* ( color_ind x y width height -- ) (?) */ @@ -143,6 +150,10 @@ molvideo_startup_splash( void )
NODE_METHODS( video ) = { +#ifdef CONFIG_MOL + {"hw-set-color", molvideo_hw_set_color }, + {"hw-refresh-palette", molvideo_refresh_palette}, +#endif {"dimensions", molvideo_dimensions }, {"set-colors", molvideo_set_colors }, {"fill-rectangle", molvideo_fill_rect },