]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Add EGA text support
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 15 Jan 2010 14:46:59 +0000 (15:46 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 15 Jan 2010 14:46:59 +0000 (15:46 +0100)
include/multiboot.h
include/multiboot2.h
loader/i386/multiboot_mbi.c

index 460347d22d6dcad29adc2580ad65e54f454f9d42..57c154c98f86507b19b62f714a5842c1f4eab061 100644 (file)
@@ -195,6 +195,9 @@ struct multiboot_info
   multiboot_uint32_t framebuffer_width;
   multiboot_uint32_t framebuffer_height;
   multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
   multiboot_uint8_t framebuffer_type;
   union
   {
@@ -223,9 +226,6 @@ struct multiboot_color
   multiboot_uint8_t blue;
 };
 
-#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
-#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
-
 struct multiboot_mmap_entry
 {
   multiboot_uint32_t size;
index 8bcf5a7e48e294b1a43b157d3d23569f49708c37..a241a70ad2311ad41beaf641fd073a7d1d3e6ad1 100644 (file)
@@ -195,6 +195,9 @@ struct multiboot_info
   multiboot_uint32_t framebuffer_width;
   multiboot_uint32_t framebuffer_height;
   multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
   multiboot_uint8_t framebuffer_type;
   union
   {
@@ -223,9 +226,6 @@ struct multiboot_color
   multiboot_uint8_t blue;
 };
 
-#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
-#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
-
 struct multiboot_mmap_entry
 {
   multiboot_uint32_t size;
index f362b800db802ea9b3611a961013fce5b3c6488e..ddbbf3cfd3133ce7dd6c8a4382d4e2071c094aef 100644 (file)
@@ -162,11 +162,12 @@ set_video_mode (void)
 #if HAS_VBE
 static grub_err_t
 fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig,
-              grub_uint32_t ptrdest)
+              grub_uint32_t ptrdest, int fill_generic)
 {
   grub_vbe_status_t status;
   grub_uint32_t vbe_mode;
   void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  struct grub_vbe_mode_info_block *mode_info;
     
   status = grub_vbe_bios_get_controller_info (scratch);
   if (status != GRUB_VBE_STATUS_OK)
@@ -180,14 +181,27 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig,
   status = grub_vbe_bios_get_mode (scratch);
   vbe_mode = *(grub_uint32_t *) scratch;
   if (status != GRUB_VBE_STATUS_OK)
-    return grub_error (GRUB_ERR_IO, "Can't get VBE mode.");
+    return grub_error (GRUB_ERR_IO, "can't get VBE mode");
   mbi->vbe_mode = vbe_mode;
 
-  status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
-  if (status != GRUB_VBE_STATUS_OK)
-    return grub_error (GRUB_ERR_IO, "Can't get mode info.");
+  mode_info = (struct grub_vbe_mode_info_block *) ptrorig;
   mbi->vbe_mode_info = ptrdest;
-  grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_mode_info_block));
+  /* get_mode_info isn't available for mode 3.  */
+  if (vbe_mode == 3)
+    {
+      grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block));
+      mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
+      mode_info->x_resolution = 80;
+      mode_info->y_resolution = 25;
+    }
+  else
+    {
+      status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
+      if (status != GRUB_VBE_STATUS_OK)
+       return grub_error (GRUB_ERR_IO, "can't get mode info");
+      grub_memcpy (mode_info, scratch,
+                  sizeof (struct grub_vbe_mode_info_block));
+    }
   ptrorig += sizeof (struct grub_vbe_mode_info_block);
   ptrdest += sizeof (struct grub_vbe_mode_info_block);
       
@@ -198,6 +212,21 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig,
   
   mbi->flags |= MULTIBOOT_INFO_VBE_INFO;
 
+  if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
+    {
+      mbi->framebuffer_addr = 0xb8000;
+
+      mbi->framebuffer_pitch = 2 * mode_info->x_resolution;    
+      mbi->framebuffer_width = mode_info->x_resolution;
+      mbi->framebuffer_height = mode_info->y_resolution;
+
+      mbi->framebuffer_bpp = 16;
+
+      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
+
+      mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
+    }
+
   return GRUB_ERR_NONE;
 }
 #endif
@@ -209,25 +238,25 @@ retrieve_video_parameters (struct multiboot_info *mbi,
   grub_err_t err;
   struct grub_video_mode_info mode_info;
   void *framebuffer;
-#if HAS_VBE
-  int vbe_active;
-#endif
+  grub_video_driver_id_t driv_id;
   struct grub_video_palette_data palette[256];
 
   err = set_video_mode ();
   if (err)
-    return err;
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
 
   grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
 
-#if HAS_VBE
-  {
-    grub_video_driver_id_t driv_id;
-    driv_id = grub_video_get_driver_id ();
-  
-    vbe_active = ((driv_id == GRUB_VIDEO_DRIVER_VBE)
-                 || ((driv_id == GRUB_VIDEO_DRIVER_NONE) && HAS_VGA_TEXT));
-  }
+  driv_id = grub_video_get_driver_id ();
+#if HAS_VGA_TEXT
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    return fill_vbe_info (mbi, ptrorig, ptrdest, 1);
+#else
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    return GRUB_ERR_NONE;
 #endif
 
   err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
@@ -277,8 +306,8 @@ retrieve_video_parameters (struct multiboot_info *mbi,
   mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
 
 #if HAS_VBE
-  if (vbe_active)
-    fill_vbe_info (mbi, ptrorig, ptrdest);
+  if (driv_id == GRUB_VIDEO_DRIVER_VBE)
+    return fill_vbe_info (mbi, ptrorig, ptrdest, 0);
 #endif
 
   return GRUB_ERR_NONE;