Added first version of the VBE terminal code.
This commit is contained in:
parent
001cf69421
commit
6323696adf
9 changed files with 1633 additions and 2 deletions
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
2005-08-16 Vesa Jaaskelainen <chaac@nic.fi>
|
||||
|
||||
* DISTLIST: Added term/i386/pc/vesafb.c
|
||||
DISTLIST: Added video/i386/pc/vbe.c
|
||||
DISTLIST: Added commands/i386/pc/vbe_list_modes.c.
|
||||
DISTLIST: Added commands/i386/pc/vbe_test.c.
|
||||
* commands/i386/pc/vbe_list_modes.c: New file.
|
||||
* commands/i386/pc/vbe_test.c: Likewise.
|
||||
* term/i386/pc/vesafb.c: Likewise.
|
||||
* video/i386/pc/vbe.c: Likewise.
|
||||
* include/grub/i386/pc/vbe.h (GRUB_VBE_DEFAULT_VIDEO_MODE): Added define.
|
||||
(grub_vbe_probe) Added prototype.
|
||||
(grub_vbe_set_video_mode) Likewise.
|
||||
(grub_vbe_get_video_mode) Likewise.
|
||||
(grub_vbe_get_video_mode_info) Likewise.
|
||||
(grub_vbe_set_pixel_rgb) Likewise.
|
||||
(grub_vbe_set_pixel_index) Likewise.
|
||||
* conf/i386-pc.rmk (pkgdata_MODULES): Added vbe.mod.
|
||||
(pkgdata_MODULES): Added vesafb.mod.
|
||||
(pkgdata_MODULES): Added vbe_list_modes.mod.
|
||||
(pkgdata_MODULES): Added vbe_test.mod.
|
||||
(vbe_mod_SOURCES): Added.
|
||||
(vbe_mod_CFLAGS): Likewise.
|
||||
(vesafb_mod_SOURCES): Likewise.
|
||||
(vesafb_mod_CFLAGS): Likewise.
|
||||
(vbe_list_modes_mod_SOURCES): Likewise.
|
||||
(vbe_list_modes_mod_CFLAGS): Likewise.
|
||||
(vbe_test_mod_SOURCES): Likewise.
|
||||
(vbe_test_mod_CFLAGS): Likewise.
|
||||
|
||||
2005-08-14 Yoshinori K. Okuji <okuji@enbug.org>
|
||||
|
||||
* normal/command.c (grub_command_execute): If INTERACTIVE is
|
||||
|
|
4
DISTLIST
4
DISTLIST
|
@ -32,6 +32,8 @@ boot/powerpc/ieee1275/cmain.c
|
|||
boot/powerpc/ieee1275/crt0.S
|
||||
commands/i386/pc/halt.c
|
||||
commands/i386/pc/reboot.c
|
||||
commands/i386/pc/vbe_list_modes.c
|
||||
commands/i386/pc/vbe_test.c
|
||||
commands/ieee1275/halt.c
|
||||
commands/ieee1275/reboot.c
|
||||
commands/ieee1275/suspend.c
|
||||
|
@ -163,6 +165,7 @@ partmap/apple.c
|
|||
partmap/pc.c
|
||||
partmap/sun.c
|
||||
term/i386/pc/console.c
|
||||
term/i386/pc/vesafb.c
|
||||
term/i386/pc/vga.c
|
||||
term/ieee1275/ofconsole.c
|
||||
util/i386/pc/biosdisk.c
|
||||
|
@ -180,3 +183,4 @@ util/grub-emu.c
|
|||
util/misc.c
|
||||
util/resolve.c
|
||||
util/unifont2pff.rb
|
||||
video/i386/pc/vbe.c
|
||||
|
|
143
commands/i386/pc/vbe_list_modes.c
Normal file
143
commands/i386/pc/vbe_list_modes.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* vbe_list_modes.c - command to list compatible VBE video modes. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <grub/normal.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/arg.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
|
||||
static void *
|
||||
real2pm(grub_vbe_farptr_t ptr)
|
||||
{
|
||||
return (void *)((((unsigned long)ptr & 0xFFFF0000) >> 12UL) +
|
||||
((unsigned long)ptr & 0x0000FFFF));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_vbe_list_modes(struct grub_arg_list *state __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_vbe_info_block controller_info;
|
||||
struct grub_vbe_mode_info_block mode_info_tmp;
|
||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
||||
grub_uint16_t *sptr;
|
||||
grub_uint32_t rc;
|
||||
char *modevar;
|
||||
|
||||
grub_printf ("List of compatible video modes:\n");
|
||||
|
||||
rc = grub_vbe_probe (&controller_info);
|
||||
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_printf ("VESA BIOS Extension not detected!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
sptr = real2pm (controller_info.video_mode_ptr);
|
||||
|
||||
/* Walk thru all video modes listed. */
|
||||
for (;*sptr != 0xFFFF; sptr++)
|
||||
{
|
||||
int valid_mode = 1;
|
||||
|
||||
rc = grub_vbe_get_video_mode_info (*sptr, &mode_info_tmp);
|
||||
if (rc != GRUB_ERR_NONE) continue;
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & 0x080) == 0)
|
||||
{
|
||||
/* We support only linear frame buffer modes. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & 0x010) == 0)
|
||||
{
|
||||
/* We allow only graphical modes. */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(mode_info_tmp.memory_model)
|
||||
{
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
break;
|
||||
|
||||
default:
|
||||
valid_mode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid_mode == 0) continue;
|
||||
|
||||
grub_printf ("0x%03x: %d x %d x %d bpp\n",
|
||||
*sptr,
|
||||
mode_info_tmp.x_resolution,
|
||||
mode_info_tmp.y_resolution,
|
||||
mode_info_tmp.bits_per_pixel);
|
||||
}
|
||||
|
||||
/* Check existence of vbe_mode environment variable. */
|
||||
modevar = grub_env_get ("vbe_mode");
|
||||
|
||||
/* Check existence of vbe_mode environment variable. */
|
||||
modevar = grub_env_get ("vbe_mode");
|
||||
|
||||
if (modevar != 0)
|
||||
{
|
||||
unsigned long value = 0;
|
||||
|
||||
if ((grub_strncmp (modevar, "0x", 2) == 0) ||
|
||||
(grub_strncmp (modevar, "0X", 2) == 0))
|
||||
{
|
||||
/* Convert HEX mode number. */
|
||||
value = grub_strtoul (modevar + 2, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert DEC mode number. */
|
||||
value = grub_strtoul (modevar, 0, 10);
|
||||
}
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
use_mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT
|
||||
{
|
||||
(void)mod; /* To stop warning. */
|
||||
grub_register_command ("vbe_list_modes", grub_cmd_vbe_list_modes, GRUB_COMMAND_FLAG_BOTH,
|
||||
"vbe_list_modes", "List compatible VESA BIOS extension video modes.", 0);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI
|
||||
{
|
||||
grub_unregister_command ("vbe_list_modes");
|
||||
}
|
195
commands/i386/pc/vbe_test.c
Normal file
195
commands/i386/pc/vbe_test.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* vbe_test.c - command to test VESA BIOS Extension 2.0+ support. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <grub/normal.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/arg.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
|
||||
static void *
|
||||
real2pm(grub_vbe_farptr_t ptr)
|
||||
{
|
||||
return (void *)((((unsigned long)ptr & 0xFFFF0000) >> 12UL) +
|
||||
((unsigned long)ptr & 0x0000FFFF));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_vbe_test(struct grub_arg_list *state __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint32_t rc;
|
||||
grub_uint16_t *sptr;
|
||||
char *modevar;
|
||||
struct grub_vbe_mode_info_block mode_info;
|
||||
struct grub_vbe_info_block controller_info;
|
||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
||||
grub_uint32_t old_mode;
|
||||
grub_uint8_t *framebuffer = 0;
|
||||
grub_uint32_t bytes_per_scan_line = 0;
|
||||
unsigned char *ptr;
|
||||
int i;
|
||||
|
||||
grub_printf ("Probing for VESA BIOS Extension ... ");
|
||||
|
||||
/* Check if VESA BIOS exists. */
|
||||
rc = grub_vbe_probe(&controller_info);
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_printf ("not found!\n");
|
||||
return rc;
|
||||
}
|
||||
grub_printf ("found!\n");
|
||||
|
||||
/* Dump out controller information. */
|
||||
grub_printf ("VBE signature = %c%c%c%c\n",
|
||||
controller_info.signature[0],
|
||||
controller_info.signature[1],
|
||||
controller_info.signature[2],
|
||||
controller_info.signature[3]);
|
||||
|
||||
grub_printf ("VBE version = %d.%d\n",
|
||||
controller_info.version >> 8,
|
||||
controller_info.version & 0xFF);
|
||||
grub_printf ("OEM string ptr = %08x\n",
|
||||
controller_info.oem_string_ptr);
|
||||
grub_printf ("Total memory = %d\n",
|
||||
controller_info.total_memory);
|
||||
|
||||
sptr = real2pm(controller_info.video_mode_ptr);
|
||||
|
||||
rc = grub_vbe_get_video_mode(&old_mode);
|
||||
grub_printf ("Get video mode rc = %04x\n", rc);
|
||||
|
||||
if (rc == GRUB_ERR_NONE)
|
||||
{
|
||||
grub_printf ("Old video mode = %04x\n", old_mode);
|
||||
}
|
||||
|
||||
/* Check existence of vbe_mode environment variable. */
|
||||
modevar = grub_env_get ("vbe_mode");
|
||||
|
||||
if (modevar != 0)
|
||||
{
|
||||
unsigned long value = 0;
|
||||
|
||||
if ((grub_strncmp (modevar, "0x", 2) == 0) ||
|
||||
(grub_strncmp (modevar, "0X", 2) == 0))
|
||||
{
|
||||
/* Convert HEX mode number. */
|
||||
value = grub_strtoul (modevar + 2, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert DEC mode number. */
|
||||
value = grub_strtoul (modevar, 0, 10);
|
||||
}
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
use_mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
rc = grub_vbe_get_video_mode_info (use_mode, &mode_info);
|
||||
|
||||
/* Dump out details about the mode being tested. */
|
||||
grub_printf ("mode: 0x%03x\n",
|
||||
use_mode);
|
||||
grub_printf ("width : %d\n",
|
||||
mode_info.x_resolution);
|
||||
grub_printf ("height: %d\n",
|
||||
mode_info.y_resolution);
|
||||
grub_printf ("memory model: %02x\n",
|
||||
mode_info.memory_model);
|
||||
grub_printf ("bytes/scanline: %d\n",
|
||||
mode_info.bytes_per_scan_line);
|
||||
grub_printf ("bytes/scanline (lin): %d\n",
|
||||
mode_info.lin_bytes_per_scan_line);
|
||||
grub_printf ("base address: %08x\n",
|
||||
mode_info.phys_base_addr);
|
||||
grub_printf ("red mask/pos: %d/%d\n",
|
||||
mode_info.red_mask_size,
|
||||
mode_info.red_field_position);
|
||||
grub_printf ("green mask/pos: %d/%d\n",
|
||||
mode_info.green_mask_size,
|
||||
mode_info.green_field_position);
|
||||
grub_printf ("blue mask/pos: %d/%d\n",
|
||||
mode_info.blue_mask_size,
|
||||
mode_info.blue_field_position);
|
||||
|
||||
grub_printf ("Press any key to continue.\n");
|
||||
|
||||
grub_getkey ();
|
||||
|
||||
/* Setup GFX mode. */
|
||||
rc = grub_vbe_set_video_mode (use_mode, &mode_info);
|
||||
|
||||
/* Determine framebuffer address and how many bytes are in scan line. */
|
||||
framebuffer = (grub_uint8_t *)mode_info.phys_base_addr;
|
||||
ptr = framebuffer;
|
||||
|
||||
if (controller_info.version >= 0x300)
|
||||
{
|
||||
bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_per_scan_line = mode_info.bytes_per_scan_line;
|
||||
}
|
||||
|
||||
/* Draw some random data to screen. */
|
||||
for (i = 0; i < 256 * 256; i++)
|
||||
{
|
||||
ptr[i] = i & 0x0F;
|
||||
}
|
||||
|
||||
/* Draw white line to screen. */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F;
|
||||
}
|
||||
|
||||
/* Draw another white line to screen. */
|
||||
grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line);
|
||||
|
||||
grub_getkey ();
|
||||
|
||||
/* Restore old video mode. */
|
||||
grub_vbe_set_video_mode (old_mode, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT
|
||||
{
|
||||
(void)mod; /* To stop warning. */
|
||||
grub_register_command ("vbe_test", grub_cmd_vbe_test, GRUB_COMMAND_FLAG_BOTH,
|
||||
"vbe_test", "Test VESA BIOS Extension 2.0+ support", 0);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI
|
||||
{
|
||||
grub_unregister_command ("vbe_test");
|
||||
}
|
203
conf/i386-pc.mk
203
conf/i386-pc.mk
|
@ -1141,7 +1141,8 @@ pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod \
|
|||
font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod \
|
||||
terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod \
|
||||
apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod \
|
||||
help.mod default.mod timeout.mod configfile.mod
|
||||
help.mod default.mod timeout.mod configfile.mod vbe.mod \
|
||||
vesafb.mod vbe_test.mod vbe_list_modes.mod
|
||||
|
||||
# For _chain.mod.
|
||||
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
|
||||
|
@ -2951,6 +2952,206 @@ fs-configfile.lst: commands/configfile.c genfslist.sh
|
|||
|
||||
|
||||
configfile_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe.mod.
|
||||
vbe_mod_SOURCES = video/i386/pc/vbe.c
|
||||
CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o def-vbe.lst und-vbe.lst
|
||||
MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d
|
||||
DEFSYMFILES += def-vbe.lst
|
||||
UNDSYMFILES += und-vbe.lst
|
||||
|
||||
vbe.mod: pre-vbe.o mod-vbe.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
|
||||
|
||||
pre-vbe.o: vbe_mod-video_i386_pc_vbe.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
|
||||
mod-vbe.o: mod-vbe.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
mod-vbe.c: moddep.lst genmodsrc.sh
|
||||
sh $(srcdir)/genmodsrc.sh 'vbe' $< > $@ || (rm -f $@; exit 1)
|
||||
|
||||
def-vbe.lst: pre-vbe.o
|
||||
$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbe/' > $@
|
||||
|
||||
und-vbe.lst: pre-vbe.o
|
||||
echo 'vbe' > $@
|
||||
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
|
||||
|
||||
vbe_mod-video_i386_pc_vbe.o: video/i386/pc/vbe.c
|
||||
$(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
vbe_mod-video_i386_pc_vbe.d: video/i386/pc/vbe.c
|
||||
set -e; $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -M $< | sed 's,vbe\.o[ :]*,vbe_mod-video_i386_pc_vbe.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
|
||||
|
||||
-include vbe_mod-video_i386_pc_vbe.d
|
||||
|
||||
CLEANFILES += cmd-vbe.lst fs-vbe.lst
|
||||
COMMANDFILES += cmd-vbe.lst
|
||||
FSFILES += fs-vbe.lst
|
||||
|
||||
cmd-vbe.lst: video/i386/pc/vbe.c gencmdlist.sh
|
||||
set -e; $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1)
|
||||
|
||||
fs-vbe.lst: video/i386/pc/vbe.c genfslist.sh
|
||||
set -e; $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
|
||||
|
||||
|
||||
vbe_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vesafb.mod.
|
||||
vesafb_mod_SOURCES = term/i386/pc/vesafb.c
|
||||
CLEANFILES += vesafb.mod mod-vesafb.o mod-vesafb.c pre-vesafb.o vesafb_mod-term_i386_pc_vesafb.o def-vesafb.lst und-vesafb.lst
|
||||
MOSTLYCLEANFILES += vesafb_mod-term_i386_pc_vesafb.d
|
||||
DEFSYMFILES += def-vesafb.lst
|
||||
UNDSYMFILES += und-vesafb.lst
|
||||
|
||||
vesafb.mod: pre-vesafb.o mod-vesafb.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
|
||||
|
||||
pre-vesafb.o: vesafb_mod-term_i386_pc_vesafb.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
|
||||
mod-vesafb.o: mod-vesafb.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(vesafb_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
mod-vesafb.c: moddep.lst genmodsrc.sh
|
||||
sh $(srcdir)/genmodsrc.sh 'vesafb' $< > $@ || (rm -f $@; exit 1)
|
||||
|
||||
def-vesafb.lst: pre-vesafb.o
|
||||
$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vesafb/' > $@
|
||||
|
||||
und-vesafb.lst: pre-vesafb.o
|
||||
echo 'vesafb' > $@
|
||||
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
|
||||
|
||||
vesafb_mod-term_i386_pc_vesafb.o: term/i386/pc/vesafb.c
|
||||
$(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(vesafb_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
vesafb_mod-term_i386_pc_vesafb.d: term/i386/pc/vesafb.c
|
||||
set -e; $(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(vesafb_mod_CFLAGS) -M $< | sed 's,vesafb\.o[ :]*,vesafb_mod-term_i386_pc_vesafb.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
|
||||
|
||||
-include vesafb_mod-term_i386_pc_vesafb.d
|
||||
|
||||
CLEANFILES += cmd-vesafb.lst fs-vesafb.lst
|
||||
COMMANDFILES += cmd-vesafb.lst
|
||||
FSFILES += fs-vesafb.lst
|
||||
|
||||
cmd-vesafb.lst: term/i386/pc/vesafb.c gencmdlist.sh
|
||||
set -e; $(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(vesafb_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vesafb > $@ || (rm -f $@; exit 1)
|
||||
|
||||
fs-vesafb.lst: term/i386/pc/vesafb.c genfslist.sh
|
||||
set -e; $(CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(CPPFLAGS) $(CFLAGS) $(vesafb_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vesafb > $@ || (rm -f $@; exit 1)
|
||||
|
||||
|
||||
vesafb_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe_list_modes.mod.
|
||||
vbe_list_modes_mod_SOURCES = commands/i386/pc/vbe_list_modes.c
|
||||
CLEANFILES += vbe_list_modes.mod mod-vbe_list_modes.o mod-vbe_list_modes.c pre-vbe_list_modes.o vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.o def-vbe_list_modes.lst und-vbe_list_modes.lst
|
||||
MOSTLYCLEANFILES += vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.d
|
||||
DEFSYMFILES += def-vbe_list_modes.lst
|
||||
UNDSYMFILES += und-vbe_list_modes.lst
|
||||
|
||||
vbe_list_modes.mod: pre-vbe_list_modes.o mod-vbe_list_modes.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
|
||||
|
||||
pre-vbe_list_modes.o: vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
|
||||
mod-vbe_list_modes.o: mod-vbe_list_modes.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(vbe_list_modes_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
mod-vbe_list_modes.c: moddep.lst genmodsrc.sh
|
||||
sh $(srcdir)/genmodsrc.sh 'vbe_list_modes' $< > $@ || (rm -f $@; exit 1)
|
||||
|
||||
def-vbe_list_modes.lst: pre-vbe_list_modes.o
|
||||
$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbe_list_modes/' > $@
|
||||
|
||||
und-vbe_list_modes.lst: pre-vbe_list_modes.o
|
||||
echo 'vbe_list_modes' > $@
|
||||
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
|
||||
|
||||
vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.o: commands/i386/pc/vbe_list_modes.c
|
||||
$(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_list_modes_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.d: commands/i386/pc/vbe_list_modes.c
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_list_modes_mod_CFLAGS) -M $< | sed 's,vbe_list_modes\.o[ :]*,vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
|
||||
|
||||
-include vbe_list_modes_mod-commands_i386_pc_vbe_list_modes.d
|
||||
|
||||
CLEANFILES += cmd-vbe_list_modes.lst fs-vbe_list_modes.lst
|
||||
COMMANDFILES += cmd-vbe_list_modes.lst
|
||||
FSFILES += fs-vbe_list_modes.lst
|
||||
|
||||
cmd-vbe_list_modes.lst: commands/i386/pc/vbe_list_modes.c gencmdlist.sh
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_list_modes_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe_list_modes > $@ || (rm -f $@; exit 1)
|
||||
|
||||
fs-vbe_list_modes.lst: commands/i386/pc/vbe_list_modes.c genfslist.sh
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_list_modes_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe_list_modes > $@ || (rm -f $@; exit 1)
|
||||
|
||||
|
||||
vbe_list_modes_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe_test.mod.
|
||||
vbe_test_mod_SOURCES = commands/i386/pc/vbe_test.c
|
||||
CLEANFILES += vbe_test.mod mod-vbe_test.o mod-vbe_test.c pre-vbe_test.o vbe_test_mod-commands_i386_pc_vbe_test.o def-vbe_test.lst und-vbe_test.lst
|
||||
MOSTLYCLEANFILES += vbe_test_mod-commands_i386_pc_vbe_test.d
|
||||
DEFSYMFILES += def-vbe_test.lst
|
||||
UNDSYMFILES += und-vbe_test.lst
|
||||
|
||||
vbe_test.mod: pre-vbe_test.o mod-vbe_test.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
|
||||
|
||||
pre-vbe_test.o: vbe_test_mod-commands_i386_pc_vbe_test.o
|
||||
-rm -f $@
|
||||
$(LD) -r -d -o $@ $^
|
||||
|
||||
mod-vbe_test.o: mod-vbe_test.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(vbe_test_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
mod-vbe_test.c: moddep.lst genmodsrc.sh
|
||||
sh $(srcdir)/genmodsrc.sh 'vbe_test' $< > $@ || (rm -f $@; exit 1)
|
||||
|
||||
def-vbe_test.lst: pre-vbe_test.o
|
||||
$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbe_test/' > $@
|
||||
|
||||
und-vbe_test.lst: pre-vbe_test.o
|
||||
echo 'vbe_test' > $@
|
||||
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
|
||||
|
||||
vbe_test_mod-commands_i386_pc_vbe_test.o: commands/i386/pc/vbe_test.c
|
||||
$(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_test_mod_CFLAGS) -c -o $@ $<
|
||||
|
||||
vbe_test_mod-commands_i386_pc_vbe_test.d: commands/i386/pc/vbe_test.c
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_test_mod_CFLAGS) -M $< | sed 's,vbe_test\.o[ :]*,vbe_test_mod-commands_i386_pc_vbe_test.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
|
||||
|
||||
-include vbe_test_mod-commands_i386_pc_vbe_test.d
|
||||
|
||||
CLEANFILES += cmd-vbe_test.lst fs-vbe_test.lst
|
||||
COMMANDFILES += cmd-vbe_test.lst
|
||||
FSFILES += fs-vbe_test.lst
|
||||
|
||||
cmd-vbe_test.lst: commands/i386/pc/vbe_test.c gencmdlist.sh
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_test_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe_test > $@ || (rm -f $@; exit 1)
|
||||
|
||||
fs-vbe_test.lst: commands/i386/pc/vbe_test.c genfslist.sh
|
||||
set -e; $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_test_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe_test > $@ || (rm -f $@; exit 1)
|
||||
|
||||
|
||||
vbe_test_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
CLEANFILES += moddep.lst command.lst fs.lst
|
||||
pkgdata_DATA += moddep.lst command.lst fs.lst
|
||||
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep
|
||||
|
|
|
@ -111,7 +111,8 @@ pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod \
|
|||
font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod \
|
||||
terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod \
|
||||
apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod \
|
||||
help.mod default.mod timeout.mod configfile.mod
|
||||
help.mod default.mod timeout.mod configfile.mod vbe.mod \
|
||||
vesafb.mod vbe_test.mod vbe_list_modes.mod
|
||||
|
||||
# For _chain.mod.
|
||||
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
|
||||
|
@ -251,3 +252,19 @@ timeout_mod_CFLAGS = $(COMMON_CFLAGS)
|
|||
# For configfile.mod
|
||||
configfile_mod_SOURCES = commands/configfile.c
|
||||
configfile_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe.mod.
|
||||
vbe_mod_SOURCES = video/i386/pc/vbe.c
|
||||
vbe_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vesafb.mod.
|
||||
vesafb_mod_SOURCES = term/i386/pc/vesafb.c
|
||||
vesafb_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe_list_modes.mod.
|
||||
vbe_list_modes_mod_SOURCES = commands/i386/pc/vbe_list_modes.c
|
||||
vbe_list_modes_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
||||
# For vbe_test.mod.
|
||||
vbe_test_mod_SOURCES = commands/i386/pc/vbe_test.c
|
||||
vbe_test_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
/* Default video mode to be used. */
|
||||
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
|
||||
|
||||
/* Note:
|
||||
|
||||
|
@ -140,6 +144,8 @@ struct grub_vbe_palette_data
|
|||
grub_uint8_t aligment;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Prototypes for kernel real mode thunks. */
|
||||
|
||||
/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */
|
||||
grub_vbe_status_t EXPORT_FUNC(grub_vbe_get_controller_info) (struct grub_vbe_info_block *controller_info);
|
||||
|
||||
|
@ -181,4 +187,13 @@ grub_vbe_status_t EXPORT_FUNC(grub_vbe_set_palette_data) (grub_uint32_t color_co
|
|||
grub_uint32_t start_index,
|
||||
struct grub_vbe_palette_data *palette_data);
|
||||
|
||||
/* Prototypes for helper functions. */
|
||||
|
||||
grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block);
|
||||
grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode, struct grub_vbe_mode_info_block *mode_info);
|
||||
grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode);
|
||||
grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode, struct grub_vbe_mode_info_block *mode_info);
|
||||
void grub_vbe_set_pixel_rgb (grub_uint32_t x, grub_uint32_t y, grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue);
|
||||
void grub_vbe_set_pixel_index (grub_uint32_t x, grub_uint32_t y, grub_uint8_t color);
|
||||
|
||||
#endif /* ! GRUB_VBE_MACHINE_HEADER */
|
||||
|
|
634
term/i386/pc/vesafb.c
Normal file
634
term/i386/pc/vesafb.c
Normal file
|
@ -0,0 +1,634 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/vga.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
#include <grub/machine/console.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/font.h>
|
||||
#include <grub/arg.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/env.h>
|
||||
|
||||
#define DEFAULT_CHAR_WIDTH 8
|
||||
#define DEFAULT_CHAR_HEIGHT 16
|
||||
|
||||
#define DEFAULT_FG_COLOR 0xa
|
||||
#define DEFAULT_BG_COLOR 0x0
|
||||
|
||||
struct grub_colored_char
|
||||
{
|
||||
/* An Unicode codepoint. */
|
||||
grub_uint32_t code;
|
||||
|
||||
/* Color indexes. */
|
||||
unsigned char fg_color;
|
||||
unsigned char bg_color;
|
||||
|
||||
/* The width of this character minus one. */
|
||||
unsigned char width;
|
||||
|
||||
/* The column index of this character. */
|
||||
unsigned char index;
|
||||
};
|
||||
|
||||
struct grub_virtual_screen
|
||||
{
|
||||
/* Dimensions of the virual screen. */
|
||||
grub_uint32_t width;
|
||||
grub_uint32_t height;
|
||||
|
||||
/* Offset in the display. */
|
||||
grub_uint32_t offset_x;
|
||||
grub_uint32_t offset_y;
|
||||
|
||||
/* TTY Character sizes. */
|
||||
grub_uint32_t char_width;
|
||||
grub_uint32_t char_height;
|
||||
|
||||
/* Virtual screen TTY size. */
|
||||
grub_uint32_t columns;
|
||||
grub_uint32_t rows;
|
||||
|
||||
/* Current cursor details. */
|
||||
grub_uint32_t cursor_x;
|
||||
grub_uint32_t cursor_y;
|
||||
grub_uint8_t cursor_state;
|
||||
grub_uint8_t fg_color;
|
||||
grub_uint8_t bg_color;
|
||||
|
||||
/* Text buffer for virual screen. Contains (columns * rows) number
|
||||
of entries. */
|
||||
struct grub_colored_char *text_buffer;
|
||||
};
|
||||
|
||||
/* Make seure text buffer is not marked as allocated. */
|
||||
static struct grub_virtual_screen virtual_screen =
|
||||
{
|
||||
.text_buffer = 0
|
||||
};
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
static unsigned char *vga_font = 0;
|
||||
static grub_uint32_t old_mode = 0;
|
||||
|
||||
static struct grub_vbe_mode_info_block mode_info;
|
||||
static grub_uint8_t *framebuffer = 0;
|
||||
static grub_uint32_t bytes_per_scan_line = 0;
|
||||
|
||||
static void
|
||||
grub_virtual_screen_free (void)
|
||||
{
|
||||
/* If virtual screen has been allocated, free it. */
|
||||
if (virtual_screen.text_buffer != 0)
|
||||
{
|
||||
grub_free (virtual_screen.text_buffer);
|
||||
}
|
||||
|
||||
/* Reset virtual screen data. */
|
||||
grub_memset (&virtual_screen, 0, sizeof(virtual_screen));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_virtual_screen_setup (grub_uint32_t width,
|
||||
grub_uint32_t height)
|
||||
{
|
||||
/* Free old virtual screen. */
|
||||
grub_virtual_screen_free ();
|
||||
|
||||
/* Initialize with default data. */
|
||||
virtual_screen.width = width;
|
||||
virtual_screen.height = height;
|
||||
virtual_screen.offset_x = 0;
|
||||
virtual_screen.offset_y = 0;
|
||||
virtual_screen.char_width = DEFAULT_CHAR_WIDTH;
|
||||
virtual_screen.char_height = DEFAULT_CHAR_HEIGHT;
|
||||
virtual_screen.cursor_x = 0;
|
||||
virtual_screen.cursor_y = 0;
|
||||
virtual_screen.cursor_state = 1;
|
||||
virtual_screen.fg_color = DEFAULT_FG_COLOR;
|
||||
virtual_screen.bg_color = DEFAULT_BG_COLOR;
|
||||
|
||||
/* Calculate size of text buffer. */
|
||||
virtual_screen.columns = virtual_screen.width / virtual_screen.char_width;
|
||||
virtual_screen.rows = virtual_screen.height / virtual_screen.char_height;
|
||||
|
||||
/* Allocate memory for text buffer. */
|
||||
virtual_screen.text_buffer =
|
||||
(struct grub_colored_char *)grub_malloc (virtual_screen.columns *
|
||||
virtual_screen.rows *
|
||||
sizeof(struct grub_colored_char));
|
||||
if (virtual_screen.text_buffer == 0)
|
||||
{
|
||||
return GRUB_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_vesafb_init (void)
|
||||
{
|
||||
grub_uint32_t rc;
|
||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
||||
struct grub_vbe_info_block controller_info;
|
||||
char *modevar;
|
||||
|
||||
/* Use fonts from VGA bios. */
|
||||
vga_font = grub_vga_get_font ();
|
||||
|
||||
/* Check if we have VESA BIOS installed. */
|
||||
rc = grub_vbe_probe (&controller_info);
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check existence of vbe_mode environment variable. */
|
||||
modevar = grub_env_get ("vbe_mode");
|
||||
|
||||
if (modevar != 0)
|
||||
{
|
||||
unsigned long value = 0;
|
||||
|
||||
if ((grub_strncmp (modevar, "0x", 2) == 0) ||
|
||||
(grub_strncmp (modevar, "0X", 2) == 0))
|
||||
{
|
||||
/* Convert HEX mode number. */
|
||||
value = grub_strtoul (modevar + 2, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert DEC mode number. */
|
||||
value = grub_strtoul (modevar, 0, 10);
|
||||
}
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
use_mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store initial video mode. */
|
||||
rc = grub_vbe_get_video_mode (&old_mode);
|
||||
|
||||
/* Setup desired graphics mode. */
|
||||
rc = grub_vbe_set_video_mode (use_mode, &mode_info);
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Determine framebuffer and bytes per scan line. */
|
||||
framebuffer = (grub_uint8_t *)mode_info.phys_base_addr;
|
||||
|
||||
if (controller_info.version >= 0x300)
|
||||
{
|
||||
bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_per_scan_line = mode_info.bytes_per_scan_line;
|
||||
}
|
||||
|
||||
/* Create virtual screen. */
|
||||
rc = grub_virtual_screen_setup (mode_info.x_resolution,
|
||||
mode_info.y_resolution);
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_vbe_set_video_mode (old_mode, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Make sure frame buffer is black. */
|
||||
grub_memset (framebuffer,
|
||||
0,
|
||||
bytes_per_scan_line * mode_info.y_resolution);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_vesafb_fini (void)
|
||||
{
|
||||
grub_virtual_screen_free ();
|
||||
|
||||
grub_vbe_set_video_mode (old_mode, 0);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_virtual_screen_get_glyph (grub_uint32_t code,
|
||||
unsigned char bitmap[32],
|
||||
unsigned *width)
|
||||
{
|
||||
if (code > 0x7f)
|
||||
{
|
||||
/* Map some unicode characters to the VGA font, if possible. */
|
||||
switch (code)
|
||||
{
|
||||
case 0x2190: /* left arrow */
|
||||
code = 0x1b;
|
||||
break;
|
||||
case 0x2191: /* up arrow */
|
||||
code = 0x18;
|
||||
break;
|
||||
case 0x2192: /* right arrow */
|
||||
code = 0x1a;
|
||||
break;
|
||||
case 0x2193: /* down arrow */
|
||||
code = 0x19;
|
||||
break;
|
||||
case 0x2501: /* horizontal line */
|
||||
code = 0xc4;
|
||||
break;
|
||||
case 0x2503: /* vertical line */
|
||||
code = 0xb3;
|
||||
break;
|
||||
case 0x250F: /* upper-left corner */
|
||||
code = 0xda;
|
||||
break;
|
||||
case 0x2513: /* upper-right corner */
|
||||
code = 0xbf;
|
||||
break;
|
||||
case 0x2517: /* lower-left corner */
|
||||
code = 0xc0;
|
||||
break;
|
||||
case 0x251B: /* lower-right corner */
|
||||
code = 0xd9;
|
||||
break;
|
||||
|
||||
default:
|
||||
return grub_font_get_glyph (code, bitmap, width);
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap)
|
||||
grub_memcpy (bitmap,
|
||||
vga_font + code * virtual_screen.char_height,
|
||||
virtual_screen.char_height);
|
||||
*width = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_invalidate_char (struct grub_colored_char *p)
|
||||
{
|
||||
p->code = 0xFFFF;
|
||||
|
||||
if (p->width)
|
||||
{
|
||||
struct grub_colored_char *q;
|
||||
|
||||
for (q = p + 1; q <= p + p->width; q++)
|
||||
{
|
||||
q->code = 0xFFFF;
|
||||
q->width = 0;
|
||||
q->index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p->width = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
write_char (void)
|
||||
{
|
||||
struct grub_colored_char *p;
|
||||
unsigned char bitmap[32];
|
||||
unsigned width;
|
||||
|
||||
p = (virtual_screen.text_buffer +
|
||||
virtual_screen.cursor_x +
|
||||
(virtual_screen.cursor_y * virtual_screen.columns));
|
||||
|
||||
p -= p->index;
|
||||
|
||||
if (! grub_virtual_screen_get_glyph (p->code, bitmap, &width))
|
||||
{
|
||||
grub_virtual_screen_invalidate_char (p);
|
||||
width = 0;
|
||||
}
|
||||
|
||||
unsigned y;
|
||||
unsigned offset;
|
||||
|
||||
for (y = 0, offset = 0;
|
||||
y < virtual_screen.char_height;
|
||||
y++, offset++)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0;
|
||||
(i < width * virtual_screen.char_width) && (offset < 32);
|
||||
i++)
|
||||
{
|
||||
unsigned char color;
|
||||
|
||||
if (bitmap[offset] & (1<<(8-i)))
|
||||
{
|
||||
color = p->fg_color;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = p->bg_color;
|
||||
}
|
||||
|
||||
grub_vbe_set_pixel_index(i + (virtual_screen.cursor_x * virtual_screen.char_width),
|
||||
y + (virtual_screen.cursor_y * virtual_screen.char_height),
|
||||
color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_cursor (void)
|
||||
{
|
||||
grub_uint32_t x;
|
||||
grub_uint32_t y;
|
||||
|
||||
for (y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3;
|
||||
y < ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 1;
|
||||
y++)
|
||||
{
|
||||
for (x = virtual_screen.cursor_x * virtual_screen.char_width;
|
||||
x < (virtual_screen.cursor_x + 1) * virtual_screen.char_width;
|
||||
x++)
|
||||
{
|
||||
grub_vbe_set_pixel_index(x, y, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scroll_up (void)
|
||||
{
|
||||
grub_uint32_t i;
|
||||
|
||||
/* Scroll text buffer with one line to up. */
|
||||
grub_memmove (virtual_screen.text_buffer,
|
||||
virtual_screen.text_buffer + virtual_screen.columns,
|
||||
sizeof (struct grub_colored_char) *
|
||||
virtual_screen.columns *
|
||||
(virtual_screen.rows - 1));
|
||||
|
||||
/* Clear last line in text buffer. */
|
||||
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
|
||||
i < virtual_screen.columns * virtual_screen.rows;
|
||||
i++)
|
||||
{
|
||||
virtual_screen.text_buffer[i].code = ' ';
|
||||
virtual_screen.text_buffer[i].fg_color = 0;
|
||||
virtual_screen.text_buffer[i].bg_color = 0;
|
||||
virtual_screen.text_buffer[i].width = 0;
|
||||
virtual_screen.text_buffer[i].index = 0;
|
||||
}
|
||||
|
||||
/* Scroll frambuffer with one line to up. */
|
||||
grub_memmove (framebuffer,
|
||||
framebuffer + bytes_per_scan_line * virtual_screen.char_height,
|
||||
bytes_per_scan_line *
|
||||
(mode_info.y_resolution - virtual_screen.char_height));
|
||||
|
||||
/* Clear last line in framebuffer. */
|
||||
grub_memset (framebuffer +
|
||||
(bytes_per_scan_line *
|
||||
(mode_info.y_resolution - virtual_screen.char_height)),
|
||||
0,
|
||||
bytes_per_scan_line * virtual_screen.char_height);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vesafb_putchar (grub_uint32_t c)
|
||||
{
|
||||
if (c == '\a')
|
||||
/* FIXME */
|
||||
return;
|
||||
|
||||
if (c == '\b' || c == '\n' || c == '\r')
|
||||
{
|
||||
/* Erase current cursor, if any. */
|
||||
if (virtual_screen.cursor_state)
|
||||
write_char ();
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\b':
|
||||
if (virtual_screen.cursor_x > 0)
|
||||
virtual_screen.cursor_x--;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
|
||||
scroll_up ();
|
||||
else
|
||||
virtual_screen.cursor_y++;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
virtual_screen.cursor_x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (virtual_screen.cursor_state)
|
||||
write_cursor ();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned width;
|
||||
struct grub_colored_char *p;
|
||||
|
||||
grub_virtual_screen_get_glyph (c, 0, &width);
|
||||
|
||||
if (virtual_screen.cursor_x + width > virtual_screen.columns)
|
||||
grub_putchar ('\n');
|
||||
|
||||
p = virtual_screen.text_buffer +
|
||||
virtual_screen.cursor_x +
|
||||
virtual_screen.cursor_y * virtual_screen.columns;
|
||||
p->code = c;
|
||||
p->fg_color = virtual_screen.fg_color;
|
||||
p->bg_color = virtual_screen.bg_color;
|
||||
p->width = width - 1;
|
||||
p->index = 0;
|
||||
|
||||
if (width > 1)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < width; i++)
|
||||
{
|
||||
p[i].code = ' ';
|
||||
p[i].width = width - 1;
|
||||
p[i].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
write_char ();
|
||||
|
||||
virtual_screen.cursor_x += width;
|
||||
if (virtual_screen.cursor_x >= virtual_screen.columns)
|
||||
{
|
||||
virtual_screen.cursor_x = 0;
|
||||
|
||||
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
|
||||
scroll_up ();
|
||||
else
|
||||
virtual_screen.cursor_y++;
|
||||
}
|
||||
|
||||
if (virtual_screen.cursor_state)
|
||||
write_cursor ();
|
||||
}
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_virtual_screen_getwh (void)
|
||||
{
|
||||
return (virtual_screen.columns << 8) | virtual_screen.rows;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_virtual_screen_getxy (void)
|
||||
{
|
||||
return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vesafb_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
if (x >= virtual_screen.columns || y >= virtual_screen.rows)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
|
||||
(unsigned) x, (unsigned) y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (virtual_screen.cursor_state)
|
||||
write_char ();
|
||||
|
||||
virtual_screen.cursor_x = x;
|
||||
virtual_screen.cursor_y = y;
|
||||
|
||||
if (virtual_screen.cursor_state)
|
||||
write_cursor ();
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_cls (void)
|
||||
{
|
||||
grub_uint32_t i;
|
||||
|
||||
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
|
||||
{
|
||||
virtual_screen.text_buffer[i].code = ' ';
|
||||
virtual_screen.text_buffer[i].fg_color = 0;
|
||||
virtual_screen.text_buffer[i].bg_color = 0;
|
||||
virtual_screen.text_buffer[i].width = 0;
|
||||
virtual_screen.text_buffer[i].index = 0;
|
||||
}
|
||||
|
||||
virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vesafb_cls (void)
|
||||
{
|
||||
grub_virtual_screen_cls ();
|
||||
|
||||
grub_memset (framebuffer,
|
||||
0,
|
||||
mode_info.y_resolution * bytes_per_scan_line);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_setcolorstate (grub_term_color_state state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
virtual_screen.fg_color = DEFAULT_FG_COLOR;
|
||||
virtual_screen.bg_color = DEFAULT_BG_COLOR;
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
virtual_screen.fg_color = DEFAULT_BG_COLOR;
|
||||
virtual_screen.bg_color = DEFAULT_FG_COLOR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_setcolor (grub_uint8_t normal_color __attribute__ ((unused)),
|
||||
grub_uint8_t highlight_color __attribute__ ((unused)))
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vesafb_setcursor (int on)
|
||||
{
|
||||
if (virtual_screen.cursor_state != on)
|
||||
{
|
||||
if (virtual_screen.cursor_state)
|
||||
write_char ();
|
||||
else
|
||||
write_cursor ();
|
||||
|
||||
virtual_screen.cursor_state = on;
|
||||
}
|
||||
}
|
||||
|
||||
static struct grub_term grub_vesafb_term =
|
||||
{
|
||||
.name = "vesafb",
|
||||
.init = grub_vesafb_init,
|
||||
.fini = grub_vesafb_fini,
|
||||
.putchar = grub_vesafb_putchar,
|
||||
.checkkey = grub_console_checkkey,
|
||||
.getkey = grub_console_getkey,
|
||||
.getwh = grub_virtual_screen_getwh,
|
||||
.getxy = grub_virtual_screen_getxy,
|
||||
.gotoxy = grub_vesafb_gotoxy,
|
||||
.cls = grub_vesafb_cls,
|
||||
.setcolorstate = grub_virtual_screen_setcolorstate,
|
||||
.setcolor = grub_virtual_screen_setcolor,
|
||||
.setcursor = grub_vesafb_setcursor,
|
||||
.flags = 0,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT
|
||||
{
|
||||
my_mod = mod;
|
||||
grub_term_register (&grub_vesafb_term);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI
|
||||
{
|
||||
grub_term_unregister (&grub_vesafb_term);
|
||||
}
|
392
video/i386/pc/vbe.c
Normal file
392
video/i386/pc/vbe.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <grub/err.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/vga.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
#include <grub/machine/console.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/font.h>
|
||||
#include <grub/arg.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/env.h>
|
||||
|
||||
/* Specify "standard" VGA palette, some video cards may
|
||||
need this and this will also be used when using RGB modes. */
|
||||
static struct grub_vbe_palette_data vga_colors[16] =
|
||||
{
|
||||
// {B, G, R, A}
|
||||
{0x00, 0x00, 0x00, 0x00}, // 0 = black
|
||||
{0xA8, 0x00, 0x00, 0x00}, // 1 = blue
|
||||
{0x00, 0xA8, 0x00, 0x00}, // 2 = green
|
||||
{0xA8, 0xA8, 0x00, 0x00}, // 3 = cyan
|
||||
{0x00, 0x00, 0xA8, 0x00}, // 4 = red
|
||||
{0xA8, 0x00, 0xA8, 0x00}, // 5 = magenta
|
||||
{0x00, 0x54, 0xA8, 0x00}, // 6 = brown
|
||||
{0xA8, 0xA8, 0xA8, 0x00}, // 7 = ligth gray
|
||||
|
||||
{0x54, 0x54, 0x54, 0x00}, // 8 = dark gray
|
||||
{0xFE, 0x54, 0x54, 0x00}, // 9 = bright blue
|
||||
{0x54, 0xFE, 0x54, 0x00}, // 10 = bright green
|
||||
{0xFE, 0xFE, 0x54, 0x00}, // 11 = bright cyan
|
||||
{0x54, 0x54, 0xFE, 0x00}, // 12 = bright red
|
||||
{0xFE, 0x54, 0xFE, 0x00}, // 13 = bright magenta
|
||||
{0x54, 0xFE, 0xFE, 0x00}, // 14 = yellow
|
||||
{0xFE, 0xFE, 0xFE, 0x00} // 15 = white
|
||||
};
|
||||
|
||||
static int vbe_detected = -1;
|
||||
static int index_color_mode = 0;
|
||||
|
||||
static struct grub_vbe_info_block controller_info;
|
||||
static struct grub_vbe_mode_info_block active_mode_info;
|
||||
|
||||
static grub_uint32_t active_mode = 0;
|
||||
|
||||
static grub_uint8_t *framebuffer = 0;
|
||||
static grub_uint32_t bytes_per_scan_line = 0;
|
||||
|
||||
grub_err_t
|
||||
grub_vbe_probe (struct grub_vbe_info_block *info_block)
|
||||
{
|
||||
struct grub_vbe_info_block *vbe_ib;
|
||||
grub_uint32_t rc;
|
||||
|
||||
/* Clear caller's controller info block. */
|
||||
if (info_block != 0)
|
||||
{
|
||||
grub_memset (info_block, 0, sizeof(struct grub_vbe_info_block));
|
||||
}
|
||||
|
||||
/* Do not probe more than one time. */
|
||||
if (vbe_detected != -1)
|
||||
{
|
||||
if (vbe_detected == 1)
|
||||
{
|
||||
/* Make copy of controller info block to caller. */
|
||||
if (info_block != 0)
|
||||
{
|
||||
grub_memcpy (info_block,
|
||||
&controller_info,
|
||||
sizeof(struct grub_vbe_info_block));
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear old copy of controller info block. */
|
||||
grub_memset (&controller_info, 0, sizeof(struct grub_vbe_info_block));
|
||||
|
||||
/* Mark VESA BIOS extension as undetected. */
|
||||
vbe_detected = 0;
|
||||
|
||||
/* Use low memory scratch area as temporary storage for VESA BIOS call. */
|
||||
vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
|
||||
|
||||
/* Prepare info block. */
|
||||
grub_memset (vbe_ib, 0, sizeof(struct grub_vbe_info_block));
|
||||
|
||||
vbe_ib->signature[0] = 'V';
|
||||
vbe_ib->signature[1] = 'B';
|
||||
vbe_ib->signature[2] = 'E';
|
||||
vbe_ib->signature[3] = '2';
|
||||
|
||||
/* Try to get controller info block. */
|
||||
rc = grub_vbe_get_controller_info (vbe_ib);
|
||||
if (rc != 0x004F)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* Copy it for later usage. */
|
||||
grub_memcpy (&controller_info,
|
||||
vbe_ib,
|
||||
sizeof(struct grub_vbe_info_block));
|
||||
|
||||
/* Copy it for caller. */
|
||||
grub_memcpy (info_block,
|
||||
vbe_ib,
|
||||
sizeof(struct grub_vbe_info_block));
|
||||
|
||||
/* Mark VESA BIOS extension as detected. */
|
||||
vbe_detected = 1;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_vbe_set_video_mode (grub_uint32_t mode,
|
||||
struct grub_vbe_mode_info_block *mode_info)
|
||||
{
|
||||
grub_uint32_t rc;
|
||||
|
||||
/* If grub_vesafb_probe has not been called or no VBE, abort. */
|
||||
if (vbe_detected == 0)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* Try to get mode info. */
|
||||
rc = grub_vbe_get_video_mode_info (mode, &active_mode_info);
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* For all VESA BIOS modes, force linear frame buffer. */
|
||||
if (mode >= 0x100)
|
||||
{
|
||||
/* We only want linear frame buffer modes. */
|
||||
mode |= 1 << 14;
|
||||
|
||||
/* Determine frame buffer pixel format. */
|
||||
switch(active_mode_info.memory_model)
|
||||
{
|
||||
case 0x04:
|
||||
index_color_mode = 1;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
index_color_mode = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to set video mode. */
|
||||
rc = grub_vbe_set_mode (mode, 0);
|
||||
if (rc != 0x004F)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* Save information for later usage. */
|
||||
active_mode = mode;
|
||||
|
||||
if (mode < 0x100)
|
||||
{
|
||||
/* If this is not a VESA mode, guess address. */
|
||||
framebuffer = (grub_uint8_t *)0xA0000;
|
||||
index_color_mode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framebuffer = (grub_uint8_t *)active_mode_info.phys_base_addr;
|
||||
|
||||
if (controller_info.version >= 0x300)
|
||||
{
|
||||
bytes_per_scan_line = active_mode_info.lin_bytes_per_scan_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_per_scan_line = active_mode_info.bytes_per_scan_line;
|
||||
}
|
||||
}
|
||||
|
||||
/* If video mode is in indexed color, setup default VGA palette. */
|
||||
if (index_color_mode != 0)
|
||||
{
|
||||
rc = grub_vbe_set_palette_data (16, 0, vga_colors);
|
||||
if (rc != 0x004F)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy mode info for caller. */
|
||||
if (mode_info != 0)
|
||||
{
|
||||
grub_memcpy (mode_info,
|
||||
&active_mode_info,
|
||||
sizeof(struct grub_vbe_mode_info_block));
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_vbe_get_video_mode (grub_uint32_t *mode)
|
||||
{
|
||||
grub_uint32_t rc;
|
||||
|
||||
/* If grub_vesafb_probe has not been called or no VBE, abort. */
|
||||
if (vbe_detected == 0)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* Try to query current mode from VESA BIOS. */
|
||||
rc = grub_vbe_get_mode (mode);
|
||||
if (rc != 0x004F)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_vbe_get_video_mode_info (grub_uint32_t mode,
|
||||
struct grub_vbe_mode_info_block *mode_info)
|
||||
{
|
||||
struct grub_vbe_mode_info_block *mi_tmp = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
|
||||
grub_uint32_t rc;
|
||||
|
||||
/* If grub_vesafb_probe has not been called or no VBE, abort. */
|
||||
if (vbe_detected == 0)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* If mode is not VESA mode, skip mode info query. */
|
||||
if (mode >= 0x100)
|
||||
{
|
||||
/* Try to get mode info from VESA BIOS. */
|
||||
rc = grub_vbe_get_mode_info (mode, mi_tmp);
|
||||
if (rc != 0x004F)
|
||||
{
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
/* Make copy of mode info block. */
|
||||
grub_memcpy (mode_info,
|
||||
mi_tmp,
|
||||
sizeof(struct grub_vbe_mode_info_block));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just clear mode info block if it isn't a VESA mode. */
|
||||
grub_memset (mode_info,
|
||||
0,
|
||||
sizeof(struct grub_vbe_mode_info_block));
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
grub_vbe_set_pixel_rgb (grub_uint32_t x,
|
||||
grub_uint32_t y,
|
||||
grub_uint8_t red,
|
||||
grub_uint8_t green,
|
||||
grub_uint8_t blue)
|
||||
{
|
||||
grub_uint32_t value;
|
||||
|
||||
if (x >= active_mode_info.x_resolution)
|
||||
return;
|
||||
|
||||
if (y >= active_mode_info.y_resolution)
|
||||
return;
|
||||
|
||||
if (controller_info.version >= 0x300)
|
||||
{
|
||||
red >>= 8 - active_mode_info.lin_red_mask_size;
|
||||
green >>= 8 - active_mode_info.lin_green_mask_size;
|
||||
blue >>= 8 - active_mode_info.lin_blue_mask_size;
|
||||
|
||||
value = red << active_mode_info.lin_red_field_position;
|
||||
value |= green << active_mode_info.lin_green_field_position;
|
||||
value |= blue << active_mode_info.lin_blue_field_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
red >>= 8 - active_mode_info.red_mask_size;
|
||||
green >>= 8 - active_mode_info.green_mask_size;
|
||||
blue >>= 8 - active_mode_info.blue_mask_size;
|
||||
|
||||
value = red << active_mode_info.red_field_position;
|
||||
value |= green << active_mode_info.green_field_position;
|
||||
value |= blue << active_mode_info.blue_field_position;
|
||||
}
|
||||
|
||||
if (active_mode_info.bits_per_pixel == 32)
|
||||
{
|
||||
grub_uint32_t *ptr = (grub_uint32_t *)(framebuffer + y * bytes_per_scan_line + x * 4);
|
||||
|
||||
*ptr = value;
|
||||
}
|
||||
else if (active_mode_info.bits_per_pixel == 24)
|
||||
{
|
||||
grub_uint8_t *ptr = (grub_uint8_t *)(framebuffer + y * bytes_per_scan_line + x * 3);
|
||||
grub_uint8_t *ptr2 = (grub_uint8_t *)&value;
|
||||
|
||||
ptr[0] = ptr2[0];
|
||||
ptr[1] = ptr2[1];
|
||||
ptr[2] = ptr2[2];
|
||||
}
|
||||
else if ((active_mode_info.bits_per_pixel == 16) ||
|
||||
(active_mode_info.bits_per_pixel == 15))
|
||||
{
|
||||
grub_uint16_t *ptr = (grub_uint16_t *)(framebuffer + y * bytes_per_scan_line + x * 2);
|
||||
|
||||
*ptr = (grub_uint16_t)(value & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
grub_vbe_set_pixel_index (grub_uint32_t x,
|
||||
grub_uint32_t y,
|
||||
grub_uint8_t color)
|
||||
{
|
||||
if (x >= active_mode_info.x_resolution)
|
||||
return;
|
||||
|
||||
if (y >= active_mode_info.y_resolution)
|
||||
return;
|
||||
|
||||
if (index_color_mode == 1)
|
||||
{
|
||||
grub_uint8_t *ptr = (grub_uint8_t *)(framebuffer + y * bytes_per_scan_line + x);
|
||||
|
||||
*ptr = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
color &= 0x0F;
|
||||
|
||||
if (color < 16)
|
||||
{
|
||||
grub_vbe_set_pixel_rgb (x,
|
||||
y,
|
||||
vga_colors[color].red,
|
||||
vga_colors[color].green,
|
||||
vga_colors[color].blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_vbe_set_pixel_rgb (x,
|
||||
y,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue