This includes the low-level VGA register accesses and also the package properties.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/vga.fs | 139 ++++++++++++++++++++++++++++++++++---- openbios-devel/drivers/vga_vbe.c | 79 ---------------------- 2 files changed, 126 insertions(+), 92 deletions(-)
diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index 538af57..1876440 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -4,40 +4,153 @@ \ This is the Forth source for an Fcode payload to initialise \ the QEMU VGA graphics card. \ +\ (C) Copyright 2013 Mark Cave-Ayland +\
fcode-version3
\ -\ Instead of using fixed values for the framebuffer address and the width -\ and height, grab the ones passed in by QEMU/generated by OpenBIOS +\ Dictionary lookups for words that don't have an FCode \
-: openbios-video-addr - " openbios-video-addr" $find if - cell+ @ +: (find-xt) \ ( str len -- xt | -1 ) + $find if + exit + else + -1 then ;
-: openbios-video-width - " openbios-video-width" $find if - cell+ @ - then +" openbios-video-addr" (find-xt) cell+ value openbios-video-addr-xt +" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt +" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt +" depth-bits" (find-xt) cell+ value depth-bits-xt +" line-bytes" (find-xt) cell+ value line-bytes-xt + +: openbios-video-addr openbios-video-addr-xt @ ; +: openbios-video-width openbios-video-width-xt @ ; +: openbios-video-height openbios-video-height-xt @ ; +: depth-bits depth-bits-xt @ ; +: line-bytes line-bytes-xt @ ; + +\ +\ IO port words +\ + +" ioc!" (find-xt) value ioc!-xt +" iow!" (find-xt) value iow!-xt + +: ioc! ioc!-xt execute ; +: iow! iow!-xt execute ; + +\ +\ VGA registers +\ + +h# 3c0 constant vga-addr +h# 3c8 constant dac-write-addr +h# 3c9 constant dac-data-addr + +: vga-color! ( r g b index -- ) + \ Set the VGA colour registers + dac-write-addr ioc! rot + 2 >> dac-data-addr ioc! swap + 2 >> dac-data-addr ioc! + 2 >> dac-data-addr ioc! ;
-: openbios-video-height - " openbios-video-height" $find if - cell+ @ - then +\ +\ VBE registers +\ + +h# 0 constant VBE_DISPI_INDEX_ID +h# 1 constant VBE_DISPI_INDEX_XRES +h# 2 constant VBE_DISPI_INDEX_YRES +h# 3 constant VBE_DISPI_INDEX_BPP +h# 4 constant VBE_DISPI_INDEX_ENABLE +h# 5 constant VBE_DISPI_INDEX_BANK +h# 6 constant VBE_DISPI_INDEX_VIRT_WIDTH +h# 7 constant VBE_DISPI_INDEX_VIRT_HEIGHT +h# 8 constant VBE_DISPI_INDEX_X_OFFSET +h# 9 constant VBE_DISPI_INDEX_Y_OFFSET +h# a constant VBE_DISPI_INDEX_NB + +h# 0 constant VBE_DISPI_DISABLED +h# 1 constant VBE_DISPI_ENABLED + +\ +\ Bochs VBE register writes +\ + +: vbe-iow! ( val addr -- ) + h# 1ce iow! + h# 1d0 iow! +; + +\ +\ Initialise Bochs VBE mode +\ + +: vbe-init ( -- ) + h# 0 vga-addr ioc! \ Enable blanking + VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe-iow! + h# 0 VBE_DISPI_INDEX_X_OFFSET vbe-iow! + h# 0 VBE_DISPI_INDEX_Y_OFFSET vbe-iow! + openbios-video-width VBE_DISPI_INDEX_XRES vbe-iow! + openbios-video-height VBE_DISPI_INDEX_YRES vbe-iow! + depth-bits VBE_DISPI_INDEX_BPP vbe-iow! + VBE_DISPI_ENABLED VBE_DISPI_INDEX_ENABLE vbe-iow! + h# 0 vga-addr ioc! + h# 20 vga-addr ioc! \ Disable blanking +; + +\ +\ Publically visible words +\ + +external + +[IFDEF] CONFIG_MOL +defer mol-color! + +\ Hook for MOL (see packages/molvideo.c) + +: hw-set-color ( r g b index -- ) + mol-color! ;
+[ELSE] + +\ Standard VGA + +: hw-set-color ( r g b index -- ) + vga-color! +; + +[THEN] + +headerless + +\ +\ Installation +\ + : qemu-vga-driver-install ( -- ) openbios-video-addr to frame-buffer-adr default-font set-font + + frame-buffer-adr encode-int " address" property + openbios-video-width encode-int " width" property + openbios-video-height encode-int " height" property + depth-bits encode-int " depth" property + line-bytes encode-int " linebytes" property + openbios-video-width openbios-video-height over char-width / over char-height / fb8-install ;
: qemu-vga-driver-init + vbe-init ['] qemu-vga-driver-install is-install ;
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 75b232e..54d9fb1 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -51,74 +51,6 @@ #define VBE_DISPI_LFB_ENABLED 0x40 #define VBE_DISPI_NOCLEARMEM 0x80
-static void vbe_outw(int index, int val) -{ - outw(index, 0x1ce); - outw(val, 0x1d0); -} - -/* for depth = 8 mode, set a hardware palette entry */ -void vga_set_color(int i, unsigned int r, unsigned int g, unsigned int b) -{ - r &= 0xff; - g &= 0xff; - b &= 0xff; - outb(i, 0x3c8); - outb(r >> 2, 0x3c9); - outb(g >> 2, 0x3c9); - outb(b >> 2, 0x3c9); -} - -/* build standard RGB palette */ -static void vga_build_rgb_palette(void) -{ - static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; - int i, r, g, b; - - i = 0; - for(r = 0; r < 6; r++) { - for(g = 0; g < 6; g++) { - for(b = 0; b < 6; b++) { - vga_set_color(i, pal_value[r], pal_value[g], pal_value[b]); - i++; - } - } - } -} - -/* depth = 8, 15, 16 or 32 */ -void vga_vbe_set_mode(int width, int height, int depth) -{ - outb(0x00, 0x3c0); /* enable blanking */ - vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED); - vbe_outw(VBE_DISPI_INDEX_X_OFFSET, 0); - vbe_outw(VBE_DISPI_INDEX_Y_OFFSET, 0); - vbe_outw(VBE_DISPI_INDEX_XRES, width); - vbe_outw(VBE_DISPI_INDEX_YRES, height); - vbe_outw(VBE_DISPI_INDEX_BPP, depth); - vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED); - outb(0x00, 0x3c0); - outb(0x20, 0x3c0); /* disable blanking */ - - if (depth == 8) - 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) @@ -136,9 +68,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, #endif
setup_video(phys, fb); - vga_vbe_set_mode(VIDEO_DICT_VALUE(video.w), - VIDEO_DICT_VALUE(video.h), - VIDEO_DICT_VALUE(video.depth));
#if 0 ph = find_dev(path); @@ -146,14 +75,6 @@ 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)); - set_int_property(ph, "linebytes", VIDEO_DICT_VALUE(video.rb)); - set_int_property(ph, "address", (u32)(fb & ~0x0000000F)); - molvideo_init();
chosen = find_dev("/chosen");