As mentioned in my previous email on-list, OpenBIOS currently contains two consoles - a C based console and a Forth based console. The Forth based console is currently broken, but is more feature complete than the C console, whilst also being more portable across different architectures.
This patchset performs the following functions:
- Fix various bugs in the Forth console - Optimise performance using low-level C graphics routines - Add simple IEEE1275-like initialisers for TCX and VGA graphics - Switch TCX and VGA drivers over to use the new console using the standard is-install word
Once this patchset is committed, a further patchset will follow to remove all of the duplicate C console code, remove packages/video.c and unify the console input/routines into libopenbios.
Mark Cave-Ayland (16): display.fs: Fix up default-font word. display.fs: Fix fb8-delete-lines within the inbuilt Forth terminal emulator. terminal.fs: Fix linefeeds on the bottom line of the Forth console. terminal.fs: Fix backspace sequence in Forth terminal. video: Create new video_common.c file for shared video primitive routines. video_common.c: Move primitive graphic operations into libopenbios/video_common.c. pci: Modify PCI display devices so that open and close words are not created automatically during initialisation. video: Create tcx.fs and vga.fs to simulate Fcode video initialisation code. display.fs: pass the colour depth in bytes to the Forth terminal routines. video_common.c: create low-level video_mask_blit() function. video_common.c: create low-level video_invert_rect() function. display.fs: Fix fb8 routines to work with bit depths > 8. video_common.c: create low-level video_fill_rect() function. display.fs: optimise scrolling by copying/deleting multiple scanlines at once. display.fs: Add vertical font-spacing as per the existing C console implementation. video: switch VGA and TCX drivers over to Forth console using is-install.
openbios-devel/arch/sparc32/console.c | 12 - openbios-devel/arch/sparc32/openbios.c | 2 +- openbios-devel/drivers/build.xml | 2 + openbios-devel/drivers/pci.c | 14 +- openbios-devel/drivers/pci.h | 1 + openbios-devel/drivers/sbus.c | 2 + openbios-devel/drivers/tcx.fs | 13 + openbios-devel/drivers/vga.fs | 13 + openbios-devel/drivers/vga_vbe.c | 2 +- openbios-devel/forth/device/display.fs | 172 +++++------ openbios-devel/forth/device/font.fs | 4 + openbios-devel/forth/device/terminal.fs | 10 +- openbios-devel/include/libopenbios/video.h | 24 ++ openbios-devel/include/packages/video.h | 6 +- openbios-devel/libopenbios/build.xml | 1 + openbios-devel/libopenbios/console_common.c | 1 + openbios-devel/libopenbios/video_common.c | 444 +++++++++++++++++++++++++++ openbios-devel/packages/video.c | 279 +---------------- 18 files changed, 607 insertions(+), 395 deletions(-) create mode 100644 openbios-devel/drivers/tcx.fs create mode 100644 openbios-devel/drivers/vga.fs create mode 100644 openbios-devel/include/libopenbios/video.h create mode 100644 openbios-devel/libopenbios/video_common.c
This enables us to execute "default-font set-font" as per the the IEEE1275 specification.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 2 +- openbios-devel/forth/device/font.fs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 1ab69ec..d85ac85 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -68,7 +68,7 @@ defer fb-emit ( x -- ) \
: default-font ( -- addr width height advance min-char #glyphs ) - \ (romfont-8x16) 8 10 10 0 100 + (romfont) (romfont-width) (romfont-height) (romfont-height) 0 100 ;
: set-font ( addr width height advance min-char #glyphs -- ) diff --git a/openbios-devel/forth/device/font.fs b/openbios-devel/forth/device/font.fs index c8100a8..7b742fa 100644 --- a/openbios-devel/forth/device/font.fs +++ b/openbios-devel/forth/device/font.fs @@ -9,5 +9,9 @@ \ the copyright and warranty status of this work. \
+0 value (romfont) +0 value (romfont-width) +0 value (romfont-height) + \ encode-file romfont.bin \ drop value (romfont-8x16)
This enables us to provide a basic scrolling console terminal.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index d85ac85..bbd2b13 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -226,12 +226,12 @@ defer fb-emit ( x -- ) dup #columns = if drop 0 to column# line# 1+ - dup #lines = if - drop - \ FIXME move up screen (and keep position) - else - to #lines + dup #lines >= if + line# + 0 to line# + 1 delete-lines then + to line# else to column# then @@ -295,12 +295,12 @@ defer fb-emit ( x -- )
: fb8-delete-lines ( n -- ) \ numcopy = ( #lines - ( line# + n )) * char-height - #lines over #line + - char-height * + #lines over line# + - char-height *
( numcopy ) 0 ?do dup line# + char-height * i + line# char-height * i + - swap fb8-copy-line + fb8-copy-line loop
#lines over - char-height *
Fix cursor position when a linefeed is entered on the bottom line.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/terminal.fs | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/openbios-devel/forth/device/terminal.fs b/openbios-devel/forth/device/terminal.fs index 3ef56ee..c9c7d59 100644 --- a/openbios-devel/forth/device/terminal.fs +++ b/openbios-devel/forth/device/terminal.fs @@ -230,6 +230,12 @@ endof a of \ LF line# 1+ to line# 0 to column# + line# #lines >= if + line# 1- + 0 to line# + 1 delete-lines + to line# + then endof b of \ VT line# 0<> if
Hi Mark,
Nice series. Time to nitpick...
--- a/openbios-devel/forth/device/terminal.fs +++ b/openbios-devel/forth/device/terminal.fs @@ -230,6 +230,12 @@ endof a of \ LF line# 1+ to line# 0 to column#
- line# #lines >= if
line# 1-
0 to line#
1 delete-lines
to line#
- then endof
This code does not handle the case when line# > #lines (should probably be an unsigned comparison anyway, as always); so make the test test for equality only? Or actually handle it, if that is useful?
Segher
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/terminal.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/openbios-devel/forth/device/terminal.fs b/openbios-devel/forth/device/terminal.fs index c9c7d59..82d3541 100644 --- a/openbios-devel/forth/device/terminal.fs +++ b/openbios-devel/forth/device/terminal.fs @@ -215,9 +215,9 @@ endof 8 of \ BS column# 0<> if - column# 1- dup + column# dup to column# - 20 draw-character + 20 draw-character 1- to column# then endof
Start by moving the get_color() and set_color() functions into the library.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/include/libopenbios/video.h | 16 +++++++ openbios-devel/include/packages/video.h | 1 - openbios-devel/libopenbios/build.xml | 1 + openbios-devel/libopenbios/console_common.c | 1 + openbios-devel/libopenbios/video_common.c | 64 +++++++++++++++++++++++++++ openbios-devel/packages/video.c | 55 +---------------------- 6 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 openbios-devel/include/libopenbios/video.h create mode 100644 openbios-devel/libopenbios/video_common.c
diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h new file mode 100644 index 0000000..dbc1747 --- /dev/null +++ b/openbios-devel/include/libopenbios/video.h @@ -0,0 +1,16 @@ + +unsigned long get_color(int col_ind); +void set_color(int ind, unsigned long color); +void video_mask_blit(void); + +typedef struct osi_fb_info { + unsigned long mphys; + unsigned long mvirt; + int rb, w, h, depth; +} osi_fb_info_t; + +struct { + int has_video; + osi_fb_info_t fb; + unsigned long *pal; /* 256 elements */ +} video; diff --git a/openbios-devel/include/packages/video.h b/openbios-devel/include/packages/video.h index 1e013b6..39ae8df 100644 --- a/openbios-devel/include/packages/video.h +++ b/openbios-devel/include/packages/video.h @@ -4,7 +4,6 @@ /* packages/video.c */ int video_get_res(int *w, int *h); void draw_pixel(int x, int y, int colind); -void set_color(int ind, unsigned long color); void video_scroll(int height); void init_video(unsigned long fb, int width, int height, int depth, int rb);
diff --git a/openbios-devel/libopenbios/build.xml b/openbios-devel/libopenbios/build.xml index 04e3800..a985a94 100644 --- a/openbios-devel/libopenbios/build.xml +++ b/openbios-devel/libopenbios/build.xml @@ -19,6 +19,7 @@ <object source="linuxbios_info.c" condition="LINUXBIOS"/> <object source="ofmem_common.c" condition="OFMEM"/> <object source="xcoff_load.c" condition="LOADER_XCOFF"/> + <object source="video_common.c"/> </library>
<dictionary name="openbios" target="forth"> diff --git a/openbios-devel/libopenbios/console_common.c b/openbios-devel/libopenbios/console_common.c index 22ec230..1631769 100644 --- a/openbios-devel/libopenbios/console_common.c +++ b/openbios-devel/libopenbios/console_common.c @@ -16,6 +16,7 @@ #include "libopenbios/bindings.h" #include "libopenbios/fontdata.h" #include "libopenbios/console.h" +#include "libopenbios/video.h" #include "packages/video.h"
#define FONT_ADJ_HEIGHT (FONT_HEIGHT + 2) diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c new file mode 100644 index 0000000..0c61e3a --- /dev/null +++ b/openbios-devel/libopenbios/video_common.c @@ -0,0 +1,64 @@ +/* + * Creation Date: <2002/10/23 20:26:40 samuel> + * Time-stamp: <2004/01/07 19:39:15 samuel> + * + * <video_common.c> + * + * Shared video routines + * + * Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + +#include "config.h" +#include "libopenbios/bindings.h" +#include "libopenbios/video.h" +#include "packages/video.h" +#include "drivers/vga.h" + + +unsigned long +get_color( int col_ind ) +{ + unsigned long col; + if( !video.has_video || col_ind < 0 || col_ind > 255 ) + return 0; + if( video.fb.depth == 8 ) + return col_ind; + col = video.pal[col_ind]; + if( video.fb.depth == 24 || video.fb.depth == 32 ) + return col; + if( video.fb.depth == 15 ) + return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f); + return 0; +} + +void +set_color( int ind, unsigned long color ) +{ + if( !video.has_video || ind < 0 || ind > 255 ) + return; + video.pal[ind] = color; + +#ifdef CONFIG_MOL + if( video.fb.depth == 8 ) + OSI_SetColor( ind, color ); +#elif defined(CONFIG_SPARC32) +#if defined(CONFIG_DEBUG_CONSOLE_VIDEO) + if( video.fb.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 +} diff --git a/openbios-devel/packages/video.c b/openbios-devel/packages/video.c index 3dbd3c5..bcc9dfc 100644 --- a/openbios-devel/packages/video.c +++ b/openbios-devel/packages/video.c @@ -20,21 +20,10 @@ #include "libopenbios/ofmem.h" #include "drivers/drivers.h" #include "packages/video.h" +#include "libopenbios/video.h" #include "libopenbios/console.h" #include "drivers/vga.h"
-typedef struct osi_fb_info { - unsigned long mphys; - unsigned long mvirt; - int rb, w, h, depth; -} osi_fb_info_t; - -static struct { - int has_video; - osi_fb_info_t fb; - unsigned long *pal; /* 256 elements */ -} video; -
int video_get_res( int *w, int *h ) @@ -103,22 +92,6 @@ startup_splash( void ) #endif }
-static unsigned long -get_color( int col_ind ) -{ - unsigned long col; - if( !video.has_video || col_ind < 0 || col_ind > 255 ) - return 0; - if( video.fb.depth == 8 ) - return col_ind; - col = video.pal[col_ind]; - if( video.fb.depth == 24 || video.fb.depth == 32 ) - return col; - if( video.fb.depth == 15 ) - return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f); - return 0; -} - void draw_pixel( int x, int y, int colind ) { @@ -177,32 +150,6 @@ refresh_palette( void ) }
void -set_color( int ind, unsigned long color ) -{ - if( !video.has_video || ind < 0 || ind > 255 ) - return; - video.pal[ind] = color; - -#ifdef CONFIG_MOL - if( video.fb.depth == 8 ) - OSI_SetColor( ind, color ); -#elif defined(CONFIG_SPARC32) -#if defined(CONFIG_DEBUG_CONSOLE_VIDEO) - if( video.fb.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 -} - -void video_scroll( int height ) { int i, offs, size, *dest, *src;
Remove several more low-level graphic primitives from packages/video.c into libopenbios/video_common.c.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/openbios.c | 2 +- openbios-devel/drivers/vga_vbe.c | 2 +- openbios-devel/include/libopenbios/video.h | 7 +- openbios-devel/include/packages/video.h | 5 +- openbios-devel/libopenbios/video_common.c | 205 ++++++++++++++++++++++++++++ openbios-devel/packages/video.c | 196 +------------------------- 6 files changed, 215 insertions(+), 202 deletions(-)
diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 53c6760..e479818 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -22,7 +22,7 @@ #include "boot.h" #include "romvec.h" #include "openprom.h" -#include "packages/video.h" +#include "libopenbios/video.h" #define NO_QEMU_PROTOS #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h" diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 569e70d..f7a736f 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -25,7 +25,7 @@ #include "asm/io.h" #include "libc/vsprintf.h" #include "drivers/vga.h" -#include "packages/video.h" +#include "libopenbios/video.h" #include "libopenbios/ofmem.h"
/* VGA init. We use the Bochs VESA VBE extensions */ diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index dbc1747..75e96c2 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -1,7 +1,12 @@
+void init_video(unsigned long fb, int width, int height, int depth, int rb); unsigned long get_color(int col_ind); void set_color(int ind, unsigned long color); -void video_mask_blit(void); +void refresh_palette(void); +int video_get_res(int *w, int *h); +void draw_pixel(int x, int y, int colind); +void video_scroll(int height); +void fill_rect(int col_ind, int x, int y, int w, int h);
typedef struct osi_fb_info { unsigned long mphys; diff --git a/openbios-devel/include/packages/video.h b/openbios-devel/include/packages/video.h index 39ae8df..2b7f412 100644 --- a/openbios-devel/include/packages/video.h +++ b/openbios-devel/include/packages/video.h @@ -2,9 +2,6 @@ #define VIDEO_SUBR_H
/* packages/video.c */ -int video_get_res(int *w, int *h); -void draw_pixel(int x, int y, int colind); -void video_scroll(int height); -void init_video(unsigned long fb, int width, int height, int depth, int rb); +void molvideo_init(void);
#endif /* VIDEO_SUBR_H */ diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 0c61e3a..0892859 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -16,6 +16,7 @@
#include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/ofmem.h" #include "libopenbios/video.h" #include "packages/video.h" #include "drivers/vga.h" @@ -62,3 +63,207 @@ set_color( int ind, unsigned long color ) (color & 0xff)); #endif } + +static void +startup_splash( void ) +{ +#ifdef CONFIG_MOL + int fd, s, i, y, x, dx, dy; + int width, height; + char *pp, *p; + char buf[64]; +#endif + + /* only draw logo in 24-bit mode (for now) */ + if( video.fb.depth < 15 ) + return; +#ifdef CONFIG_MOL + for( i=0; i<2; i++ ) { + if( !BootHGetStrResInd("bootlogo", buf, sizeof(buf), 0, i) ) + return; + *(!i ? &width : &height) = atol(buf); + } + + if( (s=width * height * 3) > 0x20000 ) + return; + + if( (fd=open_io("pseudo:,bootlogo")) >= 0 ) { + p = malloc( s ); + if( read_io(fd, p, s) != s ) + printk("bootlogo size error\n"); + close_io( fd ); + + dx = (video.fb.w - width)/2; + dy = (video.fb.h - height)/3; + + pp = (char*)video.fb.mvirt + dy * video.fb.rb + dx * (video.fb.depth >= 24 ? 4 : 2); + + for( y=0 ; y<height; y++, pp += video.fb.rb ) { + if( video.fb.depth >= 24 ) { + unsigned long *d = (unsigned long*)pp; + for( x=0; x<width; x++, p+=3, d++ ) + *d = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2]; + } else if( video.fb.depth == 15 ) { + unsigned short *d = (unsigned short*)pp; + for( x=0; x<width; x++, p+=3, d++ ) { + int col = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2]; + *d = ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f); + } + } + } + free( p ); + } +#else + /* No bootlogo support yet on other platforms */ + return; +#endif +} + +int +video_get_res( int *w, int *h ) +{ + if( !video.has_video ) { + *w = *h = 0; + return -1; + } + *w = video.fb.w; + *h = video.fb.h; + return 0; +} + +void +draw_pixel( int x, int y, int colind ) +{ + char *p = (char*)video.fb.mvirt + video.fb.rb * y; + int color, d = video.fb.depth; + + if( x < 0 || y < 0 || x >= video.fb.w || y >=video.fb.h ) + return; + color = get_color( colind ); + + if( d >= 24 ) + *((unsigned long*)p + x) = color; + else if( d >= 15 ) + *((short*)p + x) = color; + else + *(p + x) = color; +} + +void +video_scroll( int height ) +{ + int i, offs, size, *dest, *src; + + if (height <= 0 || height >= video.fb.h) { + return; + } + offs = video.fb.rb * height; + size = (video.fb.h * video.fb.rb - offs)/16; + dest = (int*)video.fb.mvirt; + src = (int*)(video.fb.mvirt + offs); + + for( i=0; i<size; i++ ) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; + dest += 4; + src += 4; + } +} + +void +fill_rect( int col_ind, int x, int y, int w, int h ) +{ + char *pp; + unsigned long col = get_color(col_ind); + + if (!video.has_video || x < 0 || y < 0 || w <= 0 || h <= 0 || + x + w > video.fb.w || y + h > video.fb.h) + return; + + pp = (char*)video.fb.mvirt + video.fb.rb * y; + for( ; h--; pp += video.fb.rb ) { + int ww = w; + if( video.fb.depth == 24 || video.fb.depth == 32 ) { + unsigned long *p = (unsigned long*)pp + x; + while( ww-- ) + *p++ = col; + } else if( video.fb.depth == 16 || video.fb.depth == 15 ) { + unsigned short *p = (unsigned short*)pp + x; + while( ww-- ) + *p++ = col; + } else { + char *p = (char *)(pp + x); + + while( ww-- ) + *p++ = col; + } + } +} + +void +refresh_palette( void ) +{ +#ifdef CONFIG_MOL + if( video.fb.depth == 8 ) + OSI_RefreshPalette(); +#endif +} + +void +init_video( unsigned long fb, int width, int height, int depth, int rb ) +{ + int i; +#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) + int size; +#endif + phandle_t ph=0, saved_ph=0; + + video.fb.mphys = video.fb.mvirt = fb; + +#if defined(CONFIG_SPARC64) + /* Fix virtual address on SPARC64 somewhere else */ + video.fb.mvirt = 0xfe000000; +#endif + + video.fb.w = width; + video.fb.h = height; + video.fb.depth = depth; + video.fb.rb = rb; + + saved_ph = get_cur_dev(); + while( (ph=dt_iterate_type(ph, "display")) ) { + set_int_property( ph, "width", video.fb.w ); + set_int_property( ph, "height", video.fb.h ); + set_int_property( ph, "depth", video.fb.depth ); + set_int_property( ph, "linebytes", video.fb.rb ); + set_int_property( ph, "address", video.fb.mvirt ); + + activate_dev(ph); + molvideo_init(); + } + video.has_video = 1; + video.pal = malloc( 256 * sizeof(unsigned long) ); + activate_dev(saved_ph); + + PUSH(video.fb.mvirt); + feval("to frame-buffer-adr"); + +#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) + size = ((video.fb.h * video.fb.rb) + 0xfff) & ~0xfff; + + ofmem_claim_phys( video.fb.mphys, size, 0 ); + ofmem_claim_virt( video.fb.mvirt, size, 0 ); + ofmem_map( video.fb.mphys, video.fb.mvirt, size, ofmem_arch_io_translation_mode(video.fb.mphys) ); +#endif + + for( i=0; i<256; i++ ) + set_color( i, i * 0x010101 ); + + set_color( 254, 0xffffcc ); + fill_rect( 254, 0, 0, video.fb.w, video.fb.h ); + + refresh_palette(); + startup_splash(); +} diff --git a/openbios-devel/packages/video.c b/openbios-devel/packages/video.c index bcc9dfc..2c2aeac 100644 --- a/openbios-devel/packages/video.c +++ b/openbios-devel/packages/video.c @@ -25,153 +25,6 @@ #include "drivers/vga.h"
-int -video_get_res( int *w, int *h ) -{ - if( !video.has_video ) { - *w = *h = 0; - return -1; - } - *w = video.fb.w; - *h = video.fb.h; - return 0; -} - -static void -startup_splash( void ) -{ -#ifdef CONFIG_MOL - int fd, s, i, y, x, dx, dy; - int width, height; - char *pp, *p; - char buf[64]; -#endif - - /* only draw logo in 24-bit mode (for now) */ - if( video.fb.depth < 15 ) - return; -#ifdef CONFIG_MOL - for( i=0; i<2; i++ ) { - if( !BootHGetStrResInd("bootlogo", buf, sizeof(buf), 0, i) ) - return; - *(!i ? &width : &height) = atol(buf); - } - - if( (s=width * height * 3) > 0x20000 ) - return; - - if( (fd=open_io("pseudo:,bootlogo")) >= 0 ) { - p = malloc( s ); - if( read_io(fd, p, s) != s ) - printk("bootlogo size error\n"); - close_io( fd ); - - dx = (video.fb.w - width)/2; - dy = (video.fb.h - height)/3; - - pp = (char*)video.fb.mvirt + dy * video.fb.rb + dx * (video.fb.depth >= 24 ? 4 : 2); - - for( y=0 ; y<height; y++, pp += video.fb.rb ) { - if( video.fb.depth >= 24 ) { - unsigned long *d = (unsigned long*)pp; - for( x=0; x<width; x++, p+=3, d++ ) - *d = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2]; - } else if( video.fb.depth == 15 ) { - unsigned short *d = (unsigned short*)pp; - for( x=0; x<width; x++, p+=3, d++ ) { - int col = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2]; - *d = ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f); - } - } - } - free( p ); - } -#else - /* No bootlogo support yet on other platforms */ - return; -#endif -} - -void -draw_pixel( int x, int y, int colind ) -{ - char *p = (char*)video.fb.mvirt + video.fb.rb * y; - int color, d = video.fb.depth; - - if( x < 0 || y < 0 || x >= video.fb.w || y >=video.fb.h ) - return; - color = get_color( colind ); - - if( d >= 24 ) - *((unsigned long*)p + x) = color; - else if( d >= 15 ) - *((short*)p + x) = color; - else - *(p + x) = color; -} - -static void -fill_rect( int col_ind, int x, int y, int w, int h ) -{ - char *pp; - unsigned long col = get_color(col_ind); - - if (!video.has_video || x < 0 || y < 0 || w <= 0 || h <= 0 || - x + w > video.fb.w || y + h > video.fb.h) - return; - - pp = (char*)video.fb.mvirt + video.fb.rb * y; - for( ; h--; pp += video.fb.rb ) { - int ww = w; - if( video.fb.depth == 24 || video.fb.depth == 32 ) { - unsigned long *p = (unsigned long*)pp + x; - while( ww-- ) - *p++ = col; - } else if( video.fb.depth == 16 || video.fb.depth == 15 ) { - unsigned short *p = (unsigned short*)pp + x; - while( ww-- ) - *p++ = col; - } else { - char *p = (char *)(pp + x); - - while( ww-- ) - *p++ = col; - } - } -} - -static void -refresh_palette( void ) -{ -#ifdef CONFIG_MOL - if( video.fb.depth == 8 ) - OSI_RefreshPalette(); -#endif -} - -void -video_scroll( int height ) -{ - int i, offs, size, *dest, *src; - - if (height <= 0 || height >= video.fb.h) { - return; - } - offs = video.fb.rb * height; - size = (video.fb.h * video.fb.rb - offs)/16; - dest = (int*)video.fb.mvirt; - src = (int*)(video.fb.mvirt + offs); - - for( i=0; i<size; i++ ) { - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - dest[3] = src[3]; - dest += 4; - src += 4; - } -} - /************************************************************************/ /* OF methods */ /************************************************************************/ @@ -259,54 +112,7 @@ NODE_METHODS( video ) = { /************************************************************************/
void -init_video( unsigned long fb, int width, int height, int depth, int rb ) +molvideo_init(void) { - int i; -#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) - int size; -#endif - phandle_t ph=0; - - video.fb.mphys = video.fb.mvirt = fb; - -#if defined(CONFIG_SPARC64) - /* Fix virtual address on SPARC64 somewhere else */ - video.fb.mvirt = 0xfe000000; -#endif - - video.fb.w = width; - video.fb.h = height; - video.fb.depth = depth; - video.fb.rb = rb; - while( (ph=dt_iterate_type(ph, "display")) ) { - set_int_property( ph, "width", video.fb.w ); - set_int_property( ph, "height", video.fb.h ); - set_int_property( ph, "depth", video.fb.depth ); - set_int_property( ph, "linebytes", video.fb.rb ); - set_int_property( ph, "address", video.fb.mvirt ); - } - video.has_video = 1; - video.pal = malloc( 256 * sizeof(unsigned long) ); - - PUSH(video.fb.mvirt); - feval("to frame-buffer-adr"); - -#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) - size = ((video.fb.h * video.fb.rb) + 0xfff) & ~0xfff; - - ofmem_claim_phys( video.fb.mphys, size, 0 ); - ofmem_claim_virt( video.fb.mvirt, size, 0 ); - ofmem_map( video.fb.mphys, video.fb.mvirt, size, ofmem_arch_io_translation_mode(video.fb.mphys) ); -#endif - - for( i=0; i<256; i++ ) - set_color( i, i * 0x010101 ); - - set_color( 254, 0xffffcc ); - fill_rect( 254, 0, 0, video.fb.w, video.fb.h ); - - refresh_palette(); - startup_splash(); - REGISTER_NODE( video ); }
This is because the work needs to be done by the "is-install" word as per the IEEE1275 specification.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/pci.c | 8 ++++++++ openbios-devel/drivers/pci.h | 1 + 2 files changed, 9 insertions(+)
diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index d6c5e51..009b974 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -44,6 +44,7 @@
DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) ); DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) ); +DECLARE_UNNAMED_NODE( ob_pci_empty_node, 0, 2*sizeof(int) );
const pci_arch_t *arch;
@@ -342,6 +343,10 @@ NODE_METHODS(ob_pci_simple_node) = { { "close", ob_pci_close }, };
+NODE_METHODS(ob_pci_empty_node) = { + { NULL, ob_pci_initialize } +}; + static void pci_set_bus_range(const pci_config_t *config) { phandle_t dev = find_dev(config->path); @@ -1230,6 +1235,9 @@ static void ob_configure_pci_device(const char* parent_path, REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle); } break; + case PCI_CLASS_DISPLAY: + REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle); + break; default: REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle); break; diff --git a/openbios-devel/drivers/pci.h b/openbios-devel/drivers/pci.h index 0f6ae1f..ab8f184 100644 --- a/openbios-devel/drivers/pci.h +++ b/openbios-devel/drivers/pci.h @@ -27,6 +27,7 @@
#define PCI_REVISION_ID 0x08 /* Revision ID */ +#define PCI_CLASS_DISPLAY 0x03 #define PCI_CLASS_PROG 0x09 #define PCI_CLASS_DEVICE 0x0a #define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
The IEEE1275 is-install routine needs to call a basic initialisation routine for each driver as typically supplied as an Fcode ROM. Provide a suitable set of basic initialisers for a QEMU host.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/build.xml | 2 ++ openbios-devel/drivers/tcx.fs | 13 +++++++++ openbios-devel/drivers/vga.fs | 13 +++++++++ openbios-devel/forth/device/display.fs | 15 ++++++++++ openbios-devel/libopenbios/video_common.c | 45 +++++++++++++++++++++++++++++ openbios-devel/packages/video.c | 15 ---------- 6 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 openbios-devel/drivers/tcx.fs create mode 100644 openbios-devel/drivers/vga.fs
diff --git a/openbios-devel/drivers/build.xml b/openbios-devel/drivers/build.xml index 75aff87..e564292 100644 --- a/openbios-devel/drivers/build.xml +++ b/openbios-devel/drivers/build.xml @@ -29,6 +29,8 @@ <object source="pci.fs" condition="DRIVER_PCI"/> <object source="sbus.fs" condition="DRIVER_SBUS"/> <object source="esp.fs" condition="DRIVER_ESP"/> + <object source="tcx.fs" condition="DRIVER_SBUS"/> + <object source="vga.fs" condition="DRIVER_VGA"/> </dictionary>
</build> diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs new file mode 100644 index 0000000..4035b45 --- /dev/null +++ b/openbios-devel/drivers/tcx.fs @@ -0,0 +1,13 @@ +\ +\ Fcode payload for QEMU TCX graphics card +\ +\ This is the Forth source for an Fcode payload to initialise +\ the QEMU TCX graphics card. +\ + +: qemu-tcx-driver-init ( -- ) + qemu-video-addr to frame-buffer-adr + default-font set-font + qemu-video-width qemu-video-height over char-width / over char-height / + fb8-install +; diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs new file mode 100644 index 0000000..632cca0 --- /dev/null +++ b/openbios-devel/drivers/vga.fs @@ -0,0 +1,13 @@ +\ +\ Fcode payload for QEMU VGA graphics card +\ +\ This is the Forth source for an Fcode payload to initialise +\ the QEMU VGA graphics card. +\ + +: qemu-vga-driver-init ( -- ) + qemu-video-addr to frame-buffer-adr + default-font set-font + qemu-video-width qemu-video-height over char-width / over char-height / + fb8-install +; diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index bbd2b13..0df7165 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -44,6 +44,10 @@ hex 0 value foreground-color 0 value background-color
+\ internal values read from QEMU firmware interface +0 value qemu-video-addr +0 value qemu-video-height +0 value qemu-video-width
\ The following wordset is called the "defer word interface" of the \ terminal-emulator support package. It gets overloaded by fb1-install @@ -102,6 +106,8 @@ defer fb-emit ( x -- ) s" open" header 1 , \ colon definition , + ['] (lit) , + -1 , ['] (semis) , reveal s" : write dup >r bounds do i c@ fb-emit loop r> ; " evaluate @@ -242,6 +248,10 @@ defer fb-emit ( x -- ) false to inverse-screen? 0 to foreground-color d# 15 to background-color + + \ override with OpenBIOS defaults + fe to background-color + 0 to foreground-color ;
: fb8-toggle-cursor ( -- ) @@ -363,4 +373,9 @@ defer fb-emit ( x -- ) then to foreground-color to background-color
+ \ ... but let's override with some better defaults + fe to background-color + 0 to foreground-color + + fb8-erase-screen ; diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 0892859..f33286b 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -16,6 +16,8 @@
#include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/console.h" +#include "libopenbios/fontdata.h" #include "libopenbios/ofmem.h" #include "libopenbios/video.h" #include "packages/video.h" @@ -211,6 +213,26 @@ refresh_palette( void ) #endif }
+static void +video_open(void) +{ + PUSH(-1); +} + +/* ( addr len -- actual ) */ +static void +video_write(void) +{ + char *addr; + int len; + + len = POP(); + addr = (char *)cell2pointer(POP()); + + console_draw_fstr(addr, len); + PUSH(len); +} + void init_video( unsigned long fb, int width, int height, int depth, int rb ) { @@ -241,6 +263,15 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) set_int_property( ph, "address", video.fb.mvirt ); activate_dev(ph); + + if (!find_package_method("open", ph)) { + bind_func("open", video_open); + } + + if (!find_package_method("write", ph)) { + bind_func("write", video_write); + } + molvideo_init(); } video.has_video = 1; @@ -250,6 +281,20 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) PUSH(video.fb.mvirt); feval("to frame-buffer-adr"); + /* Set global variables ready for fb8-install */ + PUSH((ucell)fontdata); + feval("to (romfont)"); + PUSH(FONT_HEIGHT); + feval("to (romfont-height)"); + PUSH(FONT_WIDTH); + feval("to (romfont-width)"); + PUSH(video.fb.mvirt); + feval("to qemu-video-addr"); + PUSH(video.fb.w); + feval("to qemu-video-width"); + PUSH(video.fb.h); + feval("to qemu-video-height"); + #if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) size = ((video.fb.h * video.fb.rb) + 0xfff) & ~0xfff;
diff --git a/openbios-devel/packages/video.c b/openbios-devel/packages/video.c index 2c2aeac..e68faa5 100644 --- a/openbios-devel/packages/video.c +++ b/openbios-devel/packages/video.c @@ -84,26 +84,11 @@ video_fill_rect( void ) fill_rect( color_ind, x, y, w, h ); }
-/* ( addr len -- actual ) */ -static void -video_write(void) -{ - char *addr; - int len; - - len = POP(); - addr = (char *)cell2pointer(POP()); - - console_draw_fstr(addr, len); - PUSH(len); -} - NODE_METHODS( video ) = { {"dimensions", video_dimensions }, {"set-colors", video_set_colors }, {"fill-rectangle", video_fill_rect }, {"color!", video_color_bang }, - {"write", video_write }, };
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 2 ++ openbios-devel/libopenbios/video_common.c | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 0df7165..fd4ae78 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -44,6 +44,8 @@ hex 0 value foreground-color 0 value background-color
+0 value depth-bytes + \ internal values read from QEMU firmware interface 0 value qemu-video-addr 0 value qemu-video-height diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index f33286b..71cca24 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -282,6 +282,8 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) feval("to frame-buffer-adr"); /* Set global variables ready for fb8-install */ + PUSH((video.fb.depth + 1) >> 3); + feval("to depth-bytes"); PUSH((ucell)fontdata); feval("to (romfont)"); PUSH(FONT_HEIGHT);
Switch display.fs over to use it.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 46 ++++-------------------- openbios-devel/include/libopenbios/video.h | 1 + openbios-devel/libopenbios/video_common.c | 54 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 39 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index fd4ae78..f641e46 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -162,45 +162,8 @@ defer fb-emit ( x -- )
\ 5.3.6.3.3 Generic eight-bit frame-buffer support
-\ The following two functions are unrolled for speed. - - -\ blit 8 continuous pixels described by the 8bit -\ value in bitmask8. The most significant bit is -\ painted first. - -\ this function should honour fg and bg colors - -: fb8-write-mask8 ( bitmask8 faddr -- ) - over 1 and 0<> over 7 + c! - over 2 and 0<> over 6 + c! - over 4 and 0<> over 5 + c! - over 8 and 0<> over 4 + c! - over 10 and 0<> over 3 + c! - over 20 and 0<> over 2 + c! - over 40 and 0<> over 1 + c! - over 80 and 0<> over 0 + c! - 2drop - ; - -: fb8-blitmask ( fbaddr mask-addr width height -- ) - over >r \ save width ( -- R: width ) - * 3 >> \ fbaddr mask-addr width*height/8 - bounds \ fbaddr mask-end mask - r> 0 2swap \ fbaddr width 0 mask-end mask - ?do \ ( fbaddr width l-cnt ) - 2 pick over + \ fbaddr-current - i c@ \ bitmask8 - swap fb8-write-mask8 - ( fbaddr width l-cnt ) - 8 + 2dup = if - drop swap screen-width + - swap 0 - then - ( fbaddr width l-cnt ) - loop - 2drop drop - ; +\ bind to low-level C function later +defer fb8-blitmask
: fb8-line2addr ( line -- addr ) window-top + @@ -228,6 +191,11 @@ defer fb-emit ( x -- ) line# char-height * window-top + screen-width * column# char-width * window-left + + frame-buffer-adr + swap char-width char-height + \ normal or inverse? + foreground-color background-color + inverse? if + swap + then fb8-blitmask \ now advance the position column# 1+ diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index 75e96c2..6f79b49 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -7,6 +7,7 @@ int video_get_res(int *w, int *h); void draw_pixel(int x, int y, int colind); void video_scroll(int height); void fill_rect(int col_ind, int x, int y, int w, int h); +void video_mask_blit(void);
typedef struct osi_fb_info { unsigned long mphys; diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 71cca24..9fb7962 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -133,6 +133,56 @@ video_get_res( int *w, int *h ) return 0; }
+/* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */ + +void +video_mask_blit(void) +{ + ucell bgcolor = POP(); + ucell fgcolor = POP(); + ucell height = POP(); + ucell width = POP(); + unsigned char *mask = (unsigned char *)POP(); + unsigned char *fbaddr = (unsigned char *)POP(); + + ucell color; + unsigned char *dst, *rowdst; + int x, y, m, b, d, depthbytes; + + fgcolor = get_color(fgcolor); + bgcolor = get_color(bgcolor); + d = video.fb.depth; + depthbytes = (video.fb.depth + 1) >> 3; + + dst = fbaddr; + for( y = 0; y < height; y++) { + rowdst = dst; + for( x = 0; x < (width + 1) >> 3; x++ ) { + for (b = 0; b < 8; b++) { + m = (1 << (7 - b)); + + if (*mask & m) { + color = fgcolor; + } else { + color = bgcolor; + } + + if( d >= 24 ) + *((unsigned long*)dst) = color; + else if( d >= 15 ) + *((short*)dst) = color; + else + *dst = color; + + dst += depthbytes; + } + mask++; + } + dst = rowdst; + dst += video.fb.rb; + } +} + void draw_pixel( int x, int y, int colind ) { @@ -282,6 +332,10 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) feval("to frame-buffer-adr"); /* Set global variables ready for fb8-install */ + PUSH( pointer2cell(video_mask_blit) ); + fword("is-noname-cfunc"); + feval("to fb8-blitmask"); + PUSH((video.fb.depth + 1) >> 3); feval("to depth-bytes"); PUSH((ucell)fontdata);
Switch display.fs over to use it.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 31 ++++++--------- openbios-devel/include/libopenbios/video.h | 1 + openbios-devel/libopenbios/video_common.c | 58 ++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index f641e46..f59ef1f 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -164,6 +164,7 @@ defer fb-emit ( x -- )
\ bind to low-level C function later defer fb8-blitmask +defer fb8-invertrect
: fb8-line2addr ( line -- addr ) window-top + @@ -225,15 +226,11 @@ defer fb8-blitmask ;
: fb8-toggle-cursor ( -- ) - line# char-height * window-top + screen-width * - column# char-width * window-left + + frame-buffer-adr + - char-height 0 ?do - char-width 0 ?do - dup i + dup c@ invert ff and swap c! - loop - screen-width + - loop - drop + column# char-width * window-left + + line# char-height * window-top + + char-width char-height + foreground-color background-color + fb8-invertrect ;
: fb8-erase-screen ( -- ) @@ -248,20 +245,14 @@ defer fb8-blitmask ;
: fb8-invert-screen ( -- ) - frame-buffer-adr - screen-height screen-width * - bounds ?do - i c@ case - foreground-color of background-color endof - background-color of foreground-color endof - dup - endcase - i c! - loop + 0 0 screen-width screen-height + background-color foreground-color + fb8-invertrect ;
: fb8-blink-screen ( -- ) - fb8-invert-screen fb8-invert-screen + fb8-invert-screen 2000 ms + fb8-invert-screen ;
: fb8-insert-characters ( n -- ) diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index 6f79b49..4f10eb8 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -8,6 +8,7 @@ void draw_pixel(int x, int y, int colind); void video_scroll(int height); void fill_rect(int col_ind, int x, int y, int w, int h); void video_mask_blit(void); +void video_invert_rect(void);
typedef struct osi_fb_info { unsigned long mphys; diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 9fb7962..d1a81b5 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -183,6 +183,61 @@ video_mask_blit(void) } }
+/* ( x y w h fgcolor bgcolor -- ) */ + +void +video_invert_rect( void ) +{ + ucell bgcolor = POP(); + ucell fgcolor = POP(); + int h = POP(); + int w = POP(); + int y = POP(); + int x = POP(); + char *pp; + + bgcolor = get_color(bgcolor); + fgcolor = get_color(fgcolor); + + if (!video.has_video || x < 0 || y < 0 || w <= 0 || h <= 0 || + x + w > video.fb.w || y + h > video.fb.h) + return; + + pp = (char*)video.fb.mvirt + video.fb.rb * y; + for( ; h--; pp += video.fb.rb ) { + int ww = w; + if( video.fb.depth == 24 || video.fb.depth == 32 ) { + unsigned long *p = (unsigned long*)pp + x; + while( ww-- ) { + if (*p == fgcolor) { + *p++ = bgcolor; + } else if (*p == bgcolor) { + *p++ = fgcolor; + } + } + } else if( video.fb.depth == 16 || video.fb.depth == 15 ) { + unsigned short *p = (unsigned short*)pp + x; + while( ww-- ) { + if (*p == (unsigned short)fgcolor) { + *p++ = bgcolor; + } else if (*p == (unsigned short)bgcolor) { + *p++ = fgcolor; + } + } + } else { + char *p = (char *)(pp + x); + + while( ww-- ) { + if (*p == (char)fgcolor) { + *p++ = bgcolor; + } else if (*p == (char)bgcolor) { + *p++ = fgcolor; + } + } + } + } +} + void draw_pixel( int x, int y, int colind ) { @@ -335,6 +390,9 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) PUSH( pointer2cell(video_mask_blit) ); fword("is-noname-cfunc"); feval("to fb8-blitmask"); + PUSH( pointer2cell(video_invert_rect) ); + fword("is-noname-cfunc"); + feval("to fb8-invertrect"); PUSH((video.fb.depth + 1) >> 3); feval("to depth-bytes");
The IEEE1275 specification suggests that the fb8-* routines can be coerced into working for framebuffers with greater bit depths. Make sure that we also support this.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index f59ef1f..07aaed5 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -168,7 +168,7 @@ defer fb8-invertrect
: fb8-line2addr ( line -- addr ) window-top + - screen-width * + screen-width * depth-bytes * frame-buffer-adr + window-left + ; @@ -176,12 +176,12 @@ defer fb8-invertrect : fb8-copy-line ( from to -- ) fb8-line2addr swap fb8-line2addr swap - #columns char-width * move + #columns char-width * depth-bytes * move ;
: fb8-clear-line ( line -- ) fb8-line2addr - #columns char-width * + #columns char-width * depth-bytes * background-color fill \ 0 fill ; @@ -189,8 +189,9 @@ defer fb8-invertrect : fb8-draw-character ( char -- ) \ draw the character:
font
- line# char-height * window-top + screen-width * - column# char-width * window-left + + frame-buffer-adr + + line# char-height * window-top + screen-width * depth-bytes * + column# char-width * depth-bytes * + window-left depth-bytes * + + frame-buffer-adr + swap char-width char-height \ normal or inverse? foreground-color background-color
Switch fb8-erase-screen in display.fs over to use it.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 6 +++--- openbios-devel/include/libopenbios/video.h | 1 + openbios-devel/libopenbios/video_common.c | 16 ++++++++++++++++ openbios-devel/packages/video.c | 13 ------------- 4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 07aaed5..75aa632 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -164,6 +164,7 @@ defer fb-emit ( x -- )
\ bind to low-level C function later defer fb8-blitmask +defer fb8-fillrect defer fb8-invertrect
: fb8-line2addr ( line -- addr ) @@ -235,14 +236,13 @@ defer fb8-invertrect ;
: fb8-erase-screen ( -- ) - frame-buffer-adr - screen-height screen-width * inverse-screen? if foreground-color else background-color then - fill + 0 0 screen-width screen-height + fb8-fillrect ;
: fb8-invert-screen ( -- ) diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index 4f10eb8..13bf143 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -9,6 +9,7 @@ void video_scroll(int height); void fill_rect(int col_ind, int x, int y, int w, int h); void video_mask_blit(void); void video_invert_rect(void); +void video_fill_rect(void);
typedef struct osi_fb_info { unsigned long mphys; diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index d1a81b5..203b719 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -338,6 +338,19 @@ video_write(void) PUSH(len); }
+/* ( color_ind x y width height -- ) (?) */ +void +video_fill_rect(void) +{ + int h = POP(); + int w = POP(); + int y = POP(); + int x = POP(); + int color_ind = POP(); + + fill_rect( color_ind, x, y, w, h ); +} + void init_video( unsigned long fb, int width, int height, int depth, int rb ) { @@ -390,6 +403,9 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) PUSH( pointer2cell(video_mask_blit) ); fword("is-noname-cfunc"); feval("to fb8-blitmask"); + PUSH( pointer2cell(video_fill_rect) ); + fword("is-noname-cfunc"); + feval("to fb8-fillrect"); PUSH( pointer2cell(video_invert_rect) ); fword("is-noname-cfunc"); feval("to fb8-invertrect"); diff --git a/openbios-devel/packages/video.c b/openbios-devel/packages/video.c index e68faa5..99f0c3f 100644 --- a/openbios-devel/packages/video.c +++ b/openbios-devel/packages/video.c @@ -71,19 +71,6 @@ video_color_bang( void ) refresh_palette(); }
-/* ( color_ind x y width height -- ) (?) */ -static void -video_fill_rect( void ) -{ - int h = POP(); - int w = POP(); - int y = POP(); - int x = POP(); - int color_ind = POP(); - - fill_rect( color_ind, x, y, w, h ); -} - NODE_METHODS( video ) = { {"dimensions", video_dimensions }, {"set-colors", video_set_colors },
I have recently updated to OpenBIOS r1102 and have noticed that the dir word has stopped working. I used two different hfs+ formatted disc image for testing.
On 12/03/13 04:02, Programmingkid wrote:
I have recently updated to OpenBIOS r1102 and have noticed that the dir word has stopped working. I used two different hfs+ formatted disc image for testing.
Yes I see that too - it's caused by the fix for the quik bootloader. I did a set of boot tests but missed out the auto-partition detection for dir which takes a slightly different code path.
It looks like we need to distinguish between NULL (no arguments were passed to the package) and empty arguments (the parameters were passed but were empty). The dir word can then use the latter form to correctly indicate to mac-parts that it needs to probe for the partition.
I'll take a look at this over the next few days and post a patch.
ATB,
Mark.
Change fb8-copy-line and fb8-clear-line so that they can operate on multiple lines at once, renaming to fb8-copy-lines and fb8-clear-lines respectively. Integrate these new functions into fb8-delete-lines so that they are used when scrolling the display.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 41 +++++++++++++++----------------- 1 file changed, 19 insertions(+), 22 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 75aa632..a0a182c 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -174,17 +174,20 @@ defer fb8-invertrect window-left + ;
-: fb8-copy-line ( from to -- ) - fb8-line2addr swap - fb8-line2addr swap - #columns char-width * depth-bytes * move +: fb8-copy-lines ( count from to -- ) + fb8-line2addr swap + fb8-line2addr swap + #columns char-width * depth-bytes * + 3 pick * move drop ;
-: fb8-clear-line ( line -- ) - fb8-line2addr - #columns char-width * depth-bytes * - background-color fill -\ 0 fill +: fb8-clear-lines ( count line -- ) + background-color 0 + 2 pick window-top + + #columns char-width * + 5 pick + fb8-fillrect + 2drop ;
: fb8-draw-character ( char -- ) @@ -268,20 +271,14 @@ defer fb8-invertrect : fb8-delete-lines ( n -- ) \ numcopy = ( #lines - ( line# + n )) * char-height #lines over line# + - char-height * - - ( numcopy ) 0 ?do - dup line# + char-height * i + - line# char-height * i + - fb8-copy-line - loop - - #lines over - char-height * - over char-height * - 0 ?do - dup i + fb8-clear-line - loop + over line# + char-height * + line# char-height * + fb8-copy-lines
- 2drop + #lines over - char-height * + dup #lines char-height * swap - swap + fb8-clear-lines + drop ;
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/display.fs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index a0a182c..3b6e3fa 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -44,6 +44,7 @@ hex 0 value foreground-color 0 value background-color
+2 value font-spacing 0 value depth-bytes
\ internal values read from QEMU firmware interface @@ -81,7 +82,7 @@ defer fb-emit ( x -- ) to char-num to char-min to fontbytes - to char-height + font-spacing + to char-height to char-width to font ; @@ -191,12 +192,17 @@ defer fb8-invertrect ;
: fb8-draw-character ( char -- ) + \ erase the current character + background-color + column# char-width * window-left + + line# char-height * window-top + + char-width char-height fb8-fillrect \ draw the character:
font
line# char-height * window-top + screen-width * depth-bytes * column# char-width * depth-bytes * window-left depth-bytes * + + frame-buffer-adr + - swap char-width char-height + swap char-width char-height font-spacing - \ normal or inverse? foreground-color background-color inverse? if @@ -233,7 +239,7 @@ defer fb8-invertrect : fb8-toggle-cursor ( -- ) column# char-width * window-left + line# char-height * window-top + - char-width char-height + char-width char-height font-spacing - foreground-color background-color fb8-invertrect ;
Here we install the Forth terminal console instead of the C console for the VGA and TCX drivers.
Note that this patch also disables video output for SPARC32 when CONFIG_DEBUG_CONSOLE_VIDEO is enabled, since these routines write directly to the screen instead of using the Forth bindings causing some display issues.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/console.c | 12 ------------ openbios-devel/drivers/pci.c | 6 +++++- openbios-devel/drivers/sbus.c | 2 ++ 3 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c index 2bcdf02..6fe48ac 100644 --- a/openbios-devel/arch/sparc32/console.c +++ b/openbios-devel/arch/sparc32/console.c @@ -30,15 +30,6 @@ void cls(void); unsigned char *vmem; volatile uint32_t *dac;
-static void video_putchar(int c) -{ - char buf; - - buf = c & 0xff; - - console_draw_fstr(&buf, 1); -} - static void video_cls(void) { memset((void *)vmem, 0, VMEM_SIZE); @@ -63,9 +54,6 @@ int putchar(int c) #ifdef CONFIG_DEBUG_CONSOLE_SERIAL serial_putchar(c); #endif -#ifdef CONFIG_DEBUG_CONSOLE_VIDEO - video_putchar(c); -#endif return c; }
diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index 009b974..b35492c 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -772,12 +772,16 @@ int macio_keylargo_config_cb (const pci_config_t *config)
int vga_config_cb (const pci_config_t *config) { - if (config->assigned[0] != 0x00000000) + if (config->assigned[0] != 0x00000000) { vga_vbe_init(config->path, pci_bus_addr_to_host_addr(config->assigned[0] & ~0x0000000F), config->sizes[0], pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F), config->sizes[1]); + + feval("['] qemu-vga-driver-init is-install"); + } + return 0; }
diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c index 3708a5e..06be8cd 100644 --- a/openbios-devel/drivers/sbus.c +++ b/openbios-devel/drivers/sbus.c @@ -329,6 +329,8 @@ ob_tcx_init(unsigned int slot, const char *path) fword("property"); }
+ feval("['] qemu-tcx-driver-init is-install"); + chosen = find_dev("/chosen"); push_str(path); fword("open-dev");
On Sun, Mar 10, 2013 at 4:50 PM, Mark Cave-Ayland mark.cave-ayland@ilande.co.uk wrote:
As mentioned in my previous email on-list, OpenBIOS currently contains two consoles - a C based console and a Forth based console. The Forth based console is currently broken, but is more feature complete than the C console, whilst also being more portable across different architectures.
This patchset performs the following functions:
- Fix various bugs in the Forth console
- Optimise performance using low-level C graphics routines
- Add simple IEEE1275-like initialisers for TCX and VGA graphics
- Switch TCX and VGA drivers over to use the new console using the standard is-install word
Once this patchset is committed, a further patchset will follow to remove all of the duplicate C console code, remove packages/video.c and unify the console input/routines into libopenbios.
I'm getting these warnings during build, perhaps something is not correct: LINK openbios-builtin.elf libopenbios.a(console_common.o): warning: multiple common of `video' libsparc32.a(openbios.o): warning: previous common is here libopenbios.a(video_common.o): warning: multiple common of `video' libsparc32.a(openbios.o): warning: previous common is here libpackages.a(video.o): warning: multiple common of `video' libsparc32.a(openbios.o): warning: previous common is here GEN openbios-builtin.elf.syms
Based on a quick Debian 3.1 CDROM boot test, it looks like scrolling and clear screen does not work at all. Text is also offset by one line down and one column right.
Some usual messages (CPUs, UUID) are not going to screen but that's probably OK.
Mark Cave-Ayland (16): display.fs: Fix up default-font word. display.fs: Fix fb8-delete-lines within the inbuilt Forth terminal emulator. terminal.fs: Fix linefeeds on the bottom line of the Forth console. terminal.fs: Fix backspace sequence in Forth terminal. video: Create new video_common.c file for shared video primitive routines. video_common.c: Move primitive graphic operations into libopenbios/video_common.c. pci: Modify PCI display devices so that open and close words are not created automatically during initialisation. video: Create tcx.fs and vga.fs to simulate Fcode video initialisation code. display.fs: pass the colour depth in bytes to the Forth terminal routines. video_common.c: create low-level video_mask_blit() function. video_common.c: create low-level video_invert_rect() function. display.fs: Fix fb8 routines to work with bit depths > 8. video_common.c: create low-level video_fill_rect() function. display.fs: optimise scrolling by copying/deleting multiple scanlines at once. display.fs: Add vertical font-spacing as per the existing C console implementation. video: switch VGA and TCX drivers over to Forth console using is-install.
openbios-devel/arch/sparc32/console.c | 12 - openbios-devel/arch/sparc32/openbios.c | 2 +- openbios-devel/drivers/build.xml | 2 + openbios-devel/drivers/pci.c | 14 +- openbios-devel/drivers/pci.h | 1 + openbios-devel/drivers/sbus.c | 2 + openbios-devel/drivers/tcx.fs | 13 + openbios-devel/drivers/vga.fs | 13 + openbios-devel/drivers/vga_vbe.c | 2 +- openbios-devel/forth/device/display.fs | 172 +++++------ openbios-devel/forth/device/font.fs | 4 + openbios-devel/forth/device/terminal.fs | 10 +- openbios-devel/include/libopenbios/video.h | 24 ++ openbios-devel/include/packages/video.h | 6 +- openbios-devel/libopenbios/build.xml | 1 + openbios-devel/libopenbios/console_common.c | 1 + openbios-devel/libopenbios/video_common.c | 444 +++++++++++++++++++++++++++ openbios-devel/packages/video.c | 279 +---------------- 18 files changed, 607 insertions(+), 395 deletions(-) create mode 100644 openbios-devel/drivers/tcx.fs create mode 100644 openbios-devel/drivers/vga.fs create mode 100644 openbios-devel/include/libopenbios/video.h create mode 100644 openbios-devel/libopenbios/video_common.c
-- 1.7.10.4
-- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you