]> git.pld-linux.org Git - packages/grub.git/commitdiff
- from Conectiva patches (at grub-devel list),
authordjrzulf <djrzulf@pld-linux.org>
Sat, 10 May 2003 08:30:54 +0000 (08:30 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    grub-pcpa.patch -> 1.1

grub-pcpa.patch [new file with mode: 0644]

diff --git a/grub-pcpa.patch b/grub-pcpa.patch
new file mode 100644 (file)
index 0000000..18e451d
--- /dev/null
@@ -0,0 +1,2692 @@
+diff -ru grub-0.92.orig/configure grub-0.92/configure
+--- grub-0.92.orig/configure   2002-04-28 21:13:07.000000000 -0300
++++ grub-0.92/configure        2002-06-17 21:19:23.000000000 -0300
+@@ -843,6 +843,7 @@
+   --disable-vstafs        disable VSTa FS support in Stage 2
+   --disable-jfs           disable IBM JFS support in Stage 2
+   --disable-xfs           disable SGI XFS support in Stage 2
++  --disable-vga16         disable VGA graphics interface"
+   --disable-gunzip        disable decompression in Stage 2
+   --disable-md5-password  disable MD5 password support in Stage 2
+   --disable-packet-retransmission
+@@ -4647,6 +4648,16 @@
+   FSYS_CFLAGS="$FSYS_CFLAGS -DNO_DECOMPRESSION=1"
+ fi
++# Check whether --enable-vga16 or --disable-vga16 was given.
++if test "${enable_vga16+set}" = set; then
++  enableval="$enable_vga16"
++  :
++fi
++
++if test x"$enable_vga16" != xno; then
++  STAGE2_CFLAGS="$STAGE2_CFLAGS -DVGA16=1"
++fi
++
+ # Check whether --enable-md5-password or --disable-md5-password was given.
+ if test "${enable_md5_password+set}" = set; then
+   enableval="$enable_md5_password"
+diff -ru grub-0.92.orig/lib/device.c grub-0.92/lib/device.c
+--- grub-0.92.orig/lib/device.c        2001-10-13 01:20:05.000000000 -0300
++++ grub-0.92/lib/device.c     2002-06-17 21:19:23.000000000 -0300
+@@ -664,8 +664,14 @@
+       if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+       strcpy (dev + strlen(dev) - 5, "/part");
+     }
+-  sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
+-  
++
++  sprintf (dev + strlen(dev), "%s%d",
++        /* Compaq smart and others */
++        (strncmp(dev, "/dev/ida/", 9) == 0 ||
++         strncmp(dev, "/dev/cciss/", 11) == 0 ||
++         strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
++        ((partition >> 16) & 0xFF) + 1);
++
+   /* Open the partition.  */
+   fd = open (dev, O_RDWR);
+   if (fd < 0)
+diff -ru grub-0.92.orig/stage2/asm.S grub-0.92/stage2/asm.S
+--- grub-0.92.orig/stage2/asm.S        2001-11-12 04:57:29.000000000 -0200
++++ grub-0.92/stage2/asm.S     2002-06-17 21:19:23.000000000 -0300
+@@ -1761,7 +1761,11 @@
+ VARIABLE(linux_text_len)
+       .long   0
+-      
++VARIABLE(linux_init_seg)
++      .word   LINUX_INIT_SEG
++VARIABLE(linux_setup_stack)
++      .word   LINUX_SETUP_STACK
++
+ ENTRY(linux_boot)
+       /* don't worry about saving anything, we're committed at this point */
+       cld     /* forward copying */
+@@ -1788,9 +1792,9 @@
+       /* final setup for linux boot */
+       cli
+-      movw    $LINUX_INIT_SEG, %ax
++      movw    EXT_C(linux_init_seg), %ax
+       movw    %ax, %ss
+-      movw    $LINUX_SETUP_STACK, %sp
++      movw    EXT_C(linux_setup_stack), %sp
+       
+       movw    %ax, %ds
+       movw    %ax, %es
+@@ -1801,6 +1805,7 @@
+       /* ljmp */
+       .byte   0xea
+       .word   0
++VARIABLE(linux_setup_seg)
+       .word   LINUX_SETUP_SEG
+       .code32
+@@ -1865,7 +1870,7 @@
+  *                      %cl = cursor ending scanline
+  */
+-ENTRY(nocursor)
++ENTRY(grub_nocursor)
+       push    %ebp
+       push    %ebx                    /* save EBX */
+@@ -2009,6 +2014,263 @@
+       pop     %ebp
+       ret
++#ifdef VGA16
++VARIABLE(cursorX)
++.word 0
++VARIABLE(cursorY)
++.word 0
++VARIABLE(cursorWidth)
++.word 0
++VARIABLE(cursorHeight)
++.word 0
++VARIABLE(cursorCount)
++.word 0
++VARIABLE(cursorBuf)
++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++
++/*
++ * set_int1c_handler(void)
++ */
++ENTRY(set_int1c_handler)
++      pushl   %edi
++
++      /* save the original int1c handler */
++      movl    $0x70, %edi
++      movw    (%edi), %ax
++      movw    %ax, ABS(int1c_offset)
++      movw    2(%edi), %ax
++      movw    %ax, ABS(int1c_segment)
++
++      /* save the new int1c handler */
++      movw    $ABS(int1c_handler), %ax
++      movw    %ax, (%edi)
++      xorw    %ax, %ax
++      movw    %ax, 2(%edi)
++
++      popl    %edi
++      ret
++
++
++/*
++ * unset_int1c_handler(void)
++ */
++ENTRY(unset_int1c_handler)
++      pushl   %edi
++
++      /* check if int1c_handler is set */
++      movl    $0x70, %edi
++      movw    $ABS(int1c_handler), %ax
++      cmpw    %ax, (%edi)
++      jne     int1c_1
++      xorw    %ax, %ax
++      cmpw    %ax, 2(%edi)
++      jne     int1c_1
++
++      /* restore the original */
++      movw    ABS(int1c_offset), %ax
++      movw    %ax, (%edi)
++      movw    ABS(int1c_segment), %ax
++      movw    %ax, 2(%edi)
++
++int1c_1:
++      popl    %edi
++      ret
++
++/*
++ * blinks graphics cursor
++ */
++      .code16
++write_data:
++      movw    $0, %ax
++      movw    %ax, %ds
++
++      mov     $0xA000, %ax            /* video in es:di */
++      mov     %ax, %es
++      mov     $80, %ax
++      movw    $ABS(cursorY), %si
++      mov     %ds:(%si), %bx
++      mul     %bx
++      movw    $ABS(cursorX), %si
++      mov     %ds:(%si), %bx
++      shr     $3, %bx                 /* %bx /= 8 */
++      add     %bx, %ax
++      mov     %ax, %di
++
++      movw    $ABS(cursorBuf), %si    /* fontBuf in ds:si */
++
++      /* prepare for data moving */
++      mov     $16, %dx                /* altura da fonte */
++      mov     $80, %bx                /* bytes por linha */
++
++write_loop:
++      movb    %ds:(%si), %al
++      xorb    $0xff, %al
++      movb    %al, %ds:(%si)          /* invert cursorBuf */
++      movb    %al, %es:(%di)          /* write to video */
++      add     %bx, %di
++      inc     %si
++      dec     %dx
++      jg      write_loop
++      ret
++
++int1c_handler:
++      pusha
++      mov     $0, %ax
++      mov     %ax, %ds
++      mov     $ABS(cursorCount), %si
++      mov     %ds:(%si), %ax
++      inc     %ax
++      mov     %ax, %ds:(%si)
++      cmp     $9, %ax
++      jne     int1c_done
++
++      mov     $0, %ax
++      mov     %ax, %ds:(%si)
++/*
++      movw    $0x3c4, %dx
++      movb    $0x020f, %ax
++      outw    %ax, %dx
++*/
++      call    write_data
++
++int1c_done:
++      popa
++      iret
++      /* call previous int1c handler */
++      /* ljmp */
++      .byte   0xea
++int1c_offset: .word   0
++int1c_segment:        .word   0
++      .code32
++
++
++ENTRY(get_font)
++      push    %ebp
++      push    %ebx
++      push    %ecx
++      push    %edx
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      movw    $0x1130, %ax
++      movb    $6, %bh         /* font 8x16 */
++      int     $0x10
++      movw    %bp, %dx
++      movw    %es, %cx
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      xorl    %eax, %eax
++      movw    %cx, %ax
++      shll    $4, %eax
++      movw    %dx, %ax
++
++      pop     %edx
++      pop     %ecx
++      pop     %ebx
++      pop     %ebp
++      ret
++
++/*
++ * set_videomode(mode)
++ * BIOS call "INT 10H Function 0h" to set video mode
++ *    Call with       %ah = 0x0
++ *                    %al = video mode
++ */
++ENTRY(set_videomode)
++      push    %ebp
++      push    %ebx
++      push    %ecx
++
++      movb    0x10(%esp), %cl
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      xorw    %bx, %bx
++      movb    $0xf, %ah
++      int     $0x10                   /* Get Current Video mode */
++      movb    %al, %ch
++      xorb    %ah, %ah
++      movb    %cl, %al
++        int   $0x10                   /* Set Video mode */
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      xorb    %ah, %ah
++      movb    %ch, %al
++
++      pop     %ecx
++      pop     %ebx
++      pop     %ebp
++      ret
++
++/*
++ * set_palette(index, red, green, blue)
++ * BIOS call "INT 10H Function 10h" to set individual dac register
++ *    Call with       %ah = 0x10
++ *                    %bx = register number
++ *                    %ch = new value for green (0-63)
++ *                    %cl = new value for blue (0-63)
++ *                    %dh = new value for red (0-63)
++ */
++
++ENTRY(set_palette)
++      push    %ebp
++      push    %eax
++      push    %ebx
++      push    %ecx
++      push    %edx
++
++      movw    $0x3c8, %bx             /* address write mode register */
++
++      /* wait vertical retrace */
++
++      movw    $0x3da, %dx
++l1b:  inb     %dx, %al        /* wait vertical active display */
++      test    $8, %al
++      jnz     l1b
++
++l2b:  inb     %dx, %al        /* wait vertical retrace */
++      test    $8, %al
++      jnz     l2b
++
++      mov     %bx, %dx
++      movb    0x18(%esp), %al         /* index */
++      outb    %al, %dx
++      inc     %dx
++
++      movb    0x1c(%esp), %al         /* red */
++      outb    %al, %dx
++
++      movb    0x20(%esp), %al         /* green */
++      outb    %al, %dx
++
++      movb    0x24(%esp), %al         /* blue */
++      outb    %al, %dx
++
++      movw    0x18(%esp), %bx
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      movb    %bl, %bh
++      movw    $0x1000, %ax
++      int     $0x10
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32 
++
++      pop     %edx
++      pop     %ecx
++      pop     %ebx
++      pop     %eax
++      pop     %ebp
++      ret
++#endif
+ /*
+  * getrtsecs()
+diff -ru grub-0.92.orig/stage2/boot.c grub-0.92/stage2/boot.c
+--- grub-0.92.orig/stage2/boot.c       2002-04-29 15:47:14.000000000 -0300
++++ grub-0.92/stage2/boot.c    2002-06-17 21:19:23.000000000 -0300
+@@ -28,7 +28,26 @@
+ static int cur_addr;
+ entry_func entry_addr;
+ static struct mod_list mll[99];
+-static int linux_mem_size;
++unsigned int kernel_mem = 0;
++#ifndef GRUB_UTIL
++extern short linux_init_seg, linux_setup_seg, linux_setup_stack;
++int linux_setup = LINUX_SETUP;
++int cl_my_location = CL_MY_LOCATION;
++int cl_my_end_addr = CL_MY_END_ADDR;
++int cl_base_addr = CL_BASE_ADDR;
++int linux_heap_end_offset = LINUX_HEAP_END_OFFSET;
++#else
++int linux_setup;
++int cl_my_location;
++int cl_my_end_addr;
++int cl_base_addr;
++int linux_heap_end_offset;
++#endif
++char save_kernel[128];
++char save_args[256];
++unsigned long save_load_flags;
++kernel_t save_suggested_type;
++static int ramdisk_image = 0, ramdisk_size = 0;
+ /*
+  *  The next two functions, 'load_image' and 'load_module', are the building
+@@ -40,7 +59,7 @@
+ load_image (char *kernel, char *arg, kernel_t suggested_type,
+           unsigned long load_flags)
+ {
+-  int len, i, exec_type = 0, align_4k = 1;
++  int len, i, exec_type = 0, align_4k = 1, will_fit = 1;
+   entry_func real_entry_addr = 0;
+   kernel_t type = KERNEL_TYPE_NONE;
+   unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0;
+@@ -57,6 +76,14 @@
+      executable header */
+   unsigned char buffer[MULTIBOOT_SEARCH];
++#ifdef GRUB_UTIL
++  linux_setup = LINUX_SETUP;
++  cl_my_location = CL_MY_LOCATION;
++  cl_my_end_addr = CL_MY_END_ADDR;
++  cl_base_addr = CL_BASE_ADDR;
++  linux_heap_end_offset = LINUX_HEAP_END_OFFSET;
++#endif
++
+   /* sets the header pointer to point to the beginning of the
+      buffer by default */
+   pu.aout = (struct exec *) buffer;
+@@ -211,32 +238,71 @@
+       int big_linux = 0;
+       int setup_sects = lh->setup_sects;
++      if (!(load_flags & KERNEL_REALLY_LOAD))
++      {
++        grub_strcpy(save_kernel, kernel);
++        grub_strcpy(save_args, arg);
++        save_load_flags = load_flags;
++        save_suggested_type = suggested_type;
++      }
++
+       if (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200)
+       {
+         big_linux = (lh->loadflags & LINUX_FLAG_BIG_KERNEL);
+         lh->type_of_loader = LINUX_BOOT_LOADER_TYPE;
++#ifndef GRUB_UTIL
++        if (!(load_flags & KERNEL_REALLY_LOAD))
++          {
++        /* FIXME: SETUP_SECTS should be supported up to 63.
++           But do you know there are >640KB conventional memory machines?  */
++            if (setup_sects < 60 && mbi.mem_lower < 608 && mbi.mem_lower >= 480)
++              {
++                int base_addr = ((mbi.mem_lower << 10) - 0x10000) & 0xffff00;
++
++                grub_printf("\nLess than 608 Kb of conventional memory available.\n"
++                            "This is not enough memory to load linux.\n"
++                            "Will try a workaround.\n\n");
++                linux_setup = cl_base_addr = base_addr;
++                cl_my_location = base_addr + 0x7f00;
++                cl_my_end_addr = cl_my_location + 0xff;
++                linux_init_seg = RAW_SEG(linux_setup) >> 4;
++                linux_setup_seg = linux_init_seg + 0x20;
++#if 0
++                linux_setup_stack = RAW_SEG(base_addr - 0x11000) >> 4;
++                linux_heap_end_offset = linux_setup_stack - 0x200;
++#endif
++              }
++            else
++              {
++                will_fit = (setup_sects < 60);
++                if (will_fit)
++                  load_flags |= KERNEL_REALLY_LOAD;
++              }
++          }
++#endif
++
+         if (lh->version >= 0x0201)
+           {
+-            lh->heap_end_ptr = LINUX_HEAP_END_OFFSET;
++            lh->heap_end_ptr = linux_heap_end_offset;
+             lh->loadflags |= LINUX_FLAG_CAN_USE_HEAP;
+           }
+         if (lh->version >= 0x0202)
+-          lh->cmd_line_ptr = CL_MY_LOCATION;
++          lh->cmd_line_ptr = cl_my_location;
+         else
+           {
+             lh->cl_magic = CL_MAGIC;
+-            lh->cl_offset = CL_MY_LOCATION - CL_BASE_ADDR;
++            lh->cl_offset = cl_my_location - cl_base_addr;
+             lh->setup_move_size
+-              = (unsigned short) (CL_MY_END_ADDR - CL_BASE_ADDR + 1);
++              = (unsigned short) (cl_my_end_addr - cl_base_addr + 1);
+           }
+       }
+       else
+       {
+         /* Your kernel is quite old...  */
+         lh->cl_magic = CL_MAGIC;
+-        lh->cl_offset = CL_MY_LOCATION - CL_BASE_ADDR;
++        lh->cl_offset = cl_my_location - cl_base_addr;
+         
+         setup_sects = LINUX_DEFAULT_SETUP_SECTS;
+       }
+@@ -256,12 +322,12 @@
+         return KERNEL_TYPE_NONE;
+       }
+-      grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+-                 (big_linux ? "bzImage" : "zImage"), data_len, text_len);
++      if (!(save_load_flags & KERNEL_REALLY_LOAD))
++      grub_printf ("    [Linux-%s, setup=0x%x, size=0x%x]\n",
++                   (big_linux ? "bzImage" : "zImage"), data_len, text_len);
+-      /* FIXME: SETUP_SECTS should be supported up to 63.
+-       But do you know there are >640KB conventional memory machines?  */
+-      if (mbi.mem_lower >= 608 && setup_sects < 60)
++      save_load_flags = load_flags;
++      if (will_fit)
+       {
+         /* Video mode selection support. What a mess!  */
+         /* NOTE: Even the word "mess" is not still enough to
+@@ -299,68 +365,25 @@
+             }
+         }
+-        /* Check the mem= option to limit memory used for initrd.  */
+-        {
+-          char *mem;
+-          
+-          mem = grub_strstr (arg, "mem=");
+-          if (mem)
+-            {
+-              char *value = mem + 4;
+-
+-              safe_parse_maxint (&value, &linux_mem_size);
+-              switch (errnum)
+-                {
+-                case ERR_NUMBER_OVERFLOW:
+-                  /* If an overflow occurs, use the maximum address for
+-                     initrd instead. This is good, because MAXINT is
+-                     greater than LINUX_INITRD_MAX_ADDRESS.  */
+-                  linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
+-                  errnum = ERR_NONE;
+-                  break;
+-                  
+-                case ERR_NONE:
+-                  {
+-                    int shift = 0;
+-                    
+-                    switch (grub_tolower (*value))
+-                      {
+-                      case 'g':
+-                        shift += 10;
+-                      case 'm':
+-                        shift += 10;
+-                      case 'k':
+-                        shift += 10;
+-                      default:
+-                        break;
+-                      }
+-
+-                    /* Check an overflow.  */
+-                    if (linux_mem_size > (MAXINT >> shift))
+-                      linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
+-                    else
+-                      linux_mem_size <<= shift;
+-                  }
+-                  break;
+-                  
+-                default:
+-                  linux_mem_size = 0;
+-                  errnum = ERR_NONE;
+-                  break;
+-                }
+-            }
+-          else
+-            linux_mem_size = 0;
+-        }
+-              
+-        memmove ((char *) LINUX_SETUP, buffer, data_len + SECTOR_SIZE);
++        if (load_flags & KERNEL_REALLY_LOAD)
++          {
++            if (ramdisk_size)
++              {
++                lh->ramdisk_image = ramdisk_image;
++                lh->ramdisk_size = ramdisk_size;
++              }
++            memmove ((char *) linux_setup, buffer, data_len + SECTOR_SIZE);
++          }
+         if (lh->header != LINUX_MAGIC_SIGNATURE ||
+             lh->version < 0x0200)
+-          /* Clear the heap space.  */
+-          grub_memset ((char *) LINUX_SETUP + ((setup_sects - 1) << 9),
+-                       0,
+-                       (64 - setup_sects - 1) << 9);
++          {
++              if (load_flags & KERNEL_REALLY_LOAD)
++                /* Clear the heap space.  */
++                grub_memset ((char *) linux_setup + ((setup_sects - 1) << 9),
++                             0,
++                             (64 - setup_sects - 1) << 9);
++          }
+         /* Copy command-line plus memory hack to staging area.
+            NOTE: Linux has a bug that it doesn't handle multiple spaces
+@@ -372,25 +395,40 @@
+            avoid to copy spaces unnecessarily. Hell.  */
+         {
+           char *src = skip_to (0, arg);
+-          char *dest = (char *) CL_MY_LOCATION;
++          char *mem;
++          char *dest = (char *) cl_my_location;
+-          while (((int) dest) < CL_MY_END_ADDR && *src)
++          while (((int) dest) < cl_my_end_addr && *src)
+             *(dest++) = *(src++);
+           
++/* don't add ``mem='' for 2.4 kernels :
++
++Newer machines have several regions of reserved memory outside and
++inside these regions.  grub's actions are suicide on newer laptops,
++and machines like servers with lots of memory.  Laptops have special
++sections of memory above 1MB which must be reserved... Ditto for
++ACPI tables.  Using mem=XXX completely eliminates any information
++that the BIOS has provided to the OS.
++
++*/
+           /* Add a mem option automatically only if the user doesn't
+              specify it explicitly.  */
+-          if (! grub_strstr (arg, "mem=")
+-              && ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION))
++          mem = grub_strstr (arg, "mem=") + 4;
++          if (mem != (char*)4)
++          {
++            if (safe_parse_maxint(&mem, &kernel_mem))
+             {
+-              if (dest != (char *) CL_MY_LOCATION)
+-                *(dest++) = ' ';
+-              
+-              grub_memmove (dest, "mem=", 4);
+-              dest += 4;
+-              
+-              dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400));
+-              *(dest++) = 'K';
++              if (*mem != 'K' && *mem != 'k')
++                kernel_mem *= 1024;
+             }
++            else
++            {
++              /* ERRNUM is already set inside the function
++                 safe_parse_maxint.  */
++              grub_close ();
++              return KERNEL_TYPE_NONE;
++            }
++          }
+           *dest = 0;
+         }
+@@ -399,9 +437,10 @@
+         grub_seek (data_len + SECTOR_SIZE);
+         cur_addr = LINUX_STAGING_AREA + text_len;
+-        grub_read ((char *) LINUX_STAGING_AREA, text_len);
+-        
+-        if (errnum == ERR_NONE)
++
++        if (!(load_flags & KERNEL_REALLY_LOAD) ||
++              grub_read ((char *) LINUX_STAGING_AREA, text_len)
++               >= (text_len - 16))
+           {
+             grub_close ();
+@@ -420,7 +459,8 @@
+             return big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX;
+           }
+         
+-        grub_close ();
++        else if (! errnum)
++          errnum = ERR_EXEC_FORMAT;
+       }
+       else
+       errnum = ERR_WONT_FIT;
+@@ -759,7 +799,6 @@
+ {
+   int len;
+   unsigned long moveto;
+-  struct linux_kernel_header *lh;
+   
+ #ifndef NO_DECOMPRESSION
+   no_decompression = 1;
+@@ -775,28 +814,41 @@
+       goto fail;
+     }
+-  if (linux_mem_size)
+-    moveto = linux_mem_size;
+-  else
+-    moveto = (mbi.mem_upper + 0x400) << 10;
+-  
+-  moveto = (moveto - len) & 0xfffff000;
+-  if (moveto + len >= LINUX_INITRD_MAX_ADDRESS)
+-    moveto = (LINUX_INITRD_MAX_ADDRESS - len) & 0xfffff000;
++  if (!kernel_mem)
++    kernel_mem = mbi.mem_upper;
++
++  moveto = (kernel_mem * 0x400 - (len + (0x1000 - (len % 0x1000)))) & 0xfffff000;
++  if (moveto + len > LINUX_INITRD_MAX_ADDRESS)
++    moveto = LINUX_INITRD_MAX_ADDRESS - (len + (0x1000 - (len % 0x1000)));
+   
+   /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
+      the last page.
+      XXX: Linux 2.2.xx has a bug in the memory range check, which is
+      worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh*  */
+   moveto -= 0x10000;
++
++#ifndef VGA16
+   memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
++#else
++  grub_memcpy ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
++#endif
+   printf ("   [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
+   /* FIXME: Should check if the kernel supports INITRD.  */
+-  lh = (struct linux_kernel_header *) LINUX_SETUP;
+-  lh->ramdisk_image = RAW_ADDR (moveto);
+-  lh->ramdisk_size = len;
++  if (linux_setup == LINUX_SETUP)
++    {
++      struct linux_kernel_header *lh;
++
++      lh = (struct linux_kernel_header *) linux_setup;
++      lh->ramdisk_image = RAW_ADDR (moveto);
++      lh->ramdisk_size = len;
++    }
++  else
++    {
++      ramdisk_image = RAW_ADDR (moveto);
++      ramdisk_size = len;
++    }
+   grub_close ();
+diff -ru grub-0.92.orig/stage2/builtins.c grub-0.92/stage2/builtins.c
+--- grub-0.92.orig/stage2/builtins.c   2002-04-28 21:26:49.000000000 -0300
++++ grub-0.92/stage2/builtins.c        2002-06-17 21:21:02.000000000 -0300
+@@ -80,6 +80,11 @@
+ /* The BIOS drive map.  */
+ static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
++extern char save_kernel[128];
++extern char save_args[256];
++extern unsigned long save_load_flags;
++extern kernel_t save_suggested_type;
++
+ /* Prototypes for allowing straightfoward calling of builtins functions
+    inside other functions.  */
+ static int configfile_func (char *arg, int flags);
+@@ -133,6 +138,36 @@
+   grub_printf ("[%d,%d,%d]", sector, offset, length);
+ }
++#ifdef VGA16
++/* background */
++static int
++background_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++      int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++      int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++      int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++      background = (r << 16) | (g << 8) | b;
++      if (vga_inited)
++          set_palette(0, r, g, b);
++      return (0);
++    }
++
++    return (1);
++}
++
++static struct builtin builtin_background =
++{
++  "background",
++  background_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "background RRGGBB",
++  "Sets the background color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++#endif
++
\f
+ /* blocklist */
+ static int
+@@ -235,7 +270,7 @@
+ };
+ /* boot */
+-static int
++int
+ boot_func (char *arg, int flags)
+ {
+   /* Clear the int15 handler if we can boot the kernel successfully.
+@@ -259,11 +294,25 @@
+     case KERNEL_TYPE_LINUX:
+       /* Linux */
++      if (!(save_load_flags & KERNEL_REALLY_LOAD))
++      {
++        /* "really" load, and hope nothing fails, cannot return... */
++        save_load_flags |= KERNEL_REALLY_LOAD;
++        load_image(save_kernel, save_args,
++                   save_suggested_type, save_load_flags);
++      }
+       linux_boot ();
+       break;
+     case KERNEL_TYPE_BIG_LINUX:
+       /* Big Linux */
++      if (!(save_load_flags & KERNEL_REALLY_LOAD))
++      {
++        /* "really" load, and hope nothing fails, cannot return... */
++        save_load_flags |= KERNEL_REALLY_LOAD;
++        load_image(save_kernel, save_args,
++                   save_suggested_type, save_load_flags);
++      }
+       big_linux_boot ();
+       break;
+@@ -399,6 +448,39 @@
+ #endif /* SUPPORT_NETBOOT */
\f
++#ifdef VGA16
++
++/* foreground */
++static int
++border_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++      int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++      int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++      int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++      border = (r << 16) | (g << 8) | b;
++      if (vga_inited)
++          set_palette(0x11, r, g, b);
++
++      return (0);
++    }
++
++    return (1);
++}
++
++static struct builtin builtin_border =
++{
++  "border",
++  border_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "border RRGGBB",
++  "Sets the border video color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++#endif
++
+ /* cat */
+ static int
+ cat_func (char *arg, int flags)
+@@ -409,7 +491,7 @@
+     return 1;
+   while (grub_read (&c, 1))
+-    grub_putchar (c);
++    putchar (c);
+   grub_close ();
+   return 0;
+@@ -425,8 +507,24 @@
+ };
\f
+-/* chainloader */
+ static int
++chainboot_func(char *arg, int flags)
++{
++    grub_strcpy(chainboot, arg);
++}
++
++static struct builtin builtin_chainboot =
++{
++  "chainboot",
++  chainboot_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "chainboot device",
++  "This option should be used from an installer, if the user does not "
++  "select any option, try to chainload the specified hard disk."
++};
++
++/* chainloader */
++int
+ chainloader_func (char *arg, int flags)
+ {
+   int force = 0;
+@@ -974,6 +1072,43 @@
+ };
\f
++#ifdef VGA16
++/* display */
++static int
++display_func(char *arg, int flags)
++{
++    int i;
++ 
++    for (i = 0; i < MAX_DISPLAYS; i++) {
++      if (grub_strcmp(arg, display_entries[i].name) == 0)
++          break;
++    }
++
++    if (i >= MAX_DISPLAYS)
++      return (1);
++
++    display_idx = i;
++    if (display->End)
++      (*display->End)();
++    display = &display_entries[display_idx];
++
++    /* Restart cmain */
++    grub_longjmp (restart_env, 0);
++    /*NOTREACHED*/
++
++    return (0);
++}
++ 
++static struct builtin builtin_display =
++{
++  "display",
++  display_func,
++  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
++  "display MODEL",
++  "Changes display type. Available modes are \"text\" and \"vga16\"."
++};
++#endif
++
+ /* dump FROM TO */
+ #ifdef GRUB_UTIL
+ static int
+@@ -1298,6 +1433,39 @@
+   " the devices which contain the file."
+ };
++#ifdef VGA16
++
++/* foreground */
++static int
++foreground_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++      int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++      int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++      int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++      foreground = (r << 16) | (g << 8) | b;
++      if (vga_inited)
++          set_palette(15, r, g, b);
++
++      return (0);
++    }
++
++    return (1);
++}
++
++static struct builtin builtin_foreground =
++{
++  "foreground",
++  foreground_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "foreground RRGGBB",
++  "Sets the foreground color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++#endif
++
\f
+ /* fstest */
+ static int
+@@ -1450,12 +1618,11 @@
\f
+ /* help */
+-#define MAX_SHORT_DOC_LEN     39
+-#define MAX_LONG_DOC_LEN      66
+-
+ static int
+ help_func (char *arg, int flags)
+ {
++  int MAX_SHORT_DOC_LEN = (view_x1 - view_x0 + 1) / 2 - 1;
++  int MAX_LONG_DOC_LEN = (view_x1 - view_x0) - 14;
+   int all = 0;
+   
+   if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
+@@ -1491,13 +1658,13 @@
+           len = MAX_SHORT_DOC_LEN - 1;
+         for (i = 0; i < len; i++)
+-          grub_putchar ((*builtin)->short_doc[i]);
++          putchar ((*builtin)->short_doc[i]);
+         for (; i < MAX_SHORT_DOC_LEN; i++)
+-          grub_putchar (' ');
++          putchar (' ');
+         if (! left)
+-          grub_putchar ('\n');
++          putchar ('\n');
+         left = ! left;
+       }
+@@ -1505,7 +1672,7 @@
+       /* If the last entry was at the left column, no newline was printed
+        at the end.  */
+       if (! left)
+-      grub_putchar ('\n');
++      putchar ('\n');
+     }
+   else
+     {
+@@ -1552,8 +1719,8 @@
+                     grub_printf ("    ");
+                     for (i = 0; i < len; i++)
+-                      grub_putchar (*doc++);
+-                    grub_putchar ('\n');
++                      putchar (*doc++);
++                    putchar ('\n');
+                   }
+               }
+           }
+@@ -3097,7 +3264,7 @@
+   print_fsys_type ();
+ }
+       
+-static int
++int
+ root_func (char *arg, int flags)
+ {
+   int hdbias = 0;
+@@ -3965,6 +4132,74 @@
+   " to tell GRUB the file name under your OS."
+ };
++#ifdef VGA16
++/*splashimage*/
++static int
++splashimage_func(char *arg, int flags)
++{
++    if (strlen(arg) > 63)
++      return (1);
++    if (flags == BUILTIN_CMDLINE) {
++      if (!grub_open(arg))
++          return (1);
++      grub_close();
++    }
++
++    if (flags == BUILTIN_CMDLINE || !splash_set) {
++      strcpy(splashimage, arg);
++      splash_set = 1;
++    }
++
++    if (flags == BUILTIN_CMDLINE && vga_inited) {
++      display->End();
++      display->Begin();
++      cls();
++/*    grub_longjmp(restart_env, 0);*/
++    }
++
++    return (0);
++}
++
++static struct builtin builtin_splashimage =
++{
++  "splashimage",
++  splashimage_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "splashimage FILE",
++  "Load FILE as the background image when in graphics mode."
++};
++
++/*shade*/
++static int
++shade_func(char *arg, int flags)
++{
++   int new_shade;
++
++    if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
++      return (1);
++
++    if (shade != new_shade) {
++      shade = new_shade;
++      if (flags == BUILTIN_CMDLINE && vga_inited) {
++          display->End();
++          display->Begin();
++          cls();
++      }
++    }
++
++    return (0);
++}
++
++static struct builtin builtin_shade =
++{
++  "shade",
++  shade_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "shade INTEGER",
++  "If set to 0, disables the use of shaded text, else enables it."
++};
++#endif
++
\f
+ #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+ /* terminal */
+@@ -4287,6 +4522,11 @@
+       return 0;
+     }
++#ifdef VGA16
++    if (display->End)
++      (*display->End)();
++#endif
++
+   /* Now trip to the graphics mode.  */
+   if (set_vbe_mode (mode_number | (1 << 14)) != 0x004F)
+     {
+@@ -4336,6 +4576,13 @@
+       /* Why?!  */
+       grub_reboot ();
+     }
++#ifdef VGA16  
++    if (display->Begin) {
++      if (!(*display->Begin)())
++          grub_reboot ();
++      cls();
++    }
++#endif
+   return 0;
+ }
+@@ -4573,15 +4820,79 @@
+   " the information about only the mode."
+ };
+   
++#ifdef VGA16
++
++/* viewport */
++static int
++viewport_func (char *arg, int flags)
++{
++    int i;
++    int x0 = 80, y0 = 25, x1 = 0, y1 = 0;
++    int *pos[4] = { &x0, &y0, &x1, &y1 };
++    extern int viewport_set;
++
++    if (!arg)
++      return (1);
++    for (i = 0; i < 4; i++) {
++      if (!*arg)
++          return (1);
++      while (*arg && (*arg == ' ' || *arg == '\t'))
++          ++arg;
++      if (!safe_parse_maxint(&arg, pos[i]))
++          return (1);
++      while (*arg && (*arg != ' ' && *arg != '\t'))
++          ++arg;
++    }
++
++    x1 += x0;
++    y1 += y0;
++
++    /* minimum size is 60 colums and 16 rows */
++    if (x0 > x1 - 60 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
++      return (1);
++
++    viewport_set = 1;
++    view_x0 = x0;
++    view_y0 = y0;
++    view_x1 = x1;
++    view_y1 = y1;
++
++    if (flags == BUILTIN_CMDLINE && vga_inited) {
++      display->End();
++      display->Begin();
++      cls();
++    }
++
++    return (0);
++}
++
++static struct builtin builtin_viewport =
++{
++  "viewport",
++  viewport_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "viewport x y width height",
++  "Changes grub internals to output text in the window defined by"
++  " four parameters. The x and y parameters are 0 based. This option"
++  " only works with the vga interface."
++};
++#endif
++
\f
+ /* The table of builtin commands. Sorted in dictionary order.  */
+ struct builtin *builtin_table[] =
+ {
++#ifdef VGA16
++  &builtin_background,
++#endif
+   &builtin_blocklist,
+   &builtin_boot,
+ #ifdef SUPPORT_NETBOOT
+   &builtin_bootp,
+ #endif /* SUPPORT_NETBOOT */
++#ifdef VGA16
++  &builtin_border,
++#endif
+   &builtin_cat,
+   &builtin_chainloader,
+   &builtin_cmp,
+@@ -4595,6 +4906,9 @@
+ #ifdef SUPPORT_NETBOOT
+   &builtin_dhcp,
+ #endif /* SUPPORT_NETBOOT */
++#ifdef VGA16
++  &builtin_display,
++#endif
+   &builtin_displayapm,
+   &builtin_displaymem,
+ #ifdef GRUB_UTIL
+@@ -4603,6 +4917,9 @@
+   &builtin_embed,
+   &builtin_fallback,
+   &builtin_find,
++#ifdef VGA16
++  &builtin_foreground,
++#endif
+   &builtin_fstest,
+   &builtin_geometry,
+   &builtin_halt,
+@@ -4646,6 +4963,10 @@
+ #endif /* SUPPORT_SERIAL */
+   &builtin_setkey,
+   &builtin_setup,
++#ifdef VGA16
++  &builtin_shade,
++  &builtin_splashimage,
++#endif
+ #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+   &builtin_terminal,
+ #endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+@@ -4659,5 +4980,8 @@
+   &builtin_unhide,
+   &builtin_uppermem,
+   &builtin_vbeprobe,
++#ifdef VGA16
++  &builtin_viewport,
++#endif
+   0
+ };
+diff -ru grub-0.92.orig/stage2/char_io.c grub-0.92/stage2/char_io.c
+--- grub-0.92.orig/stage2/char_io.c    2002-03-25 18:43:55.000000000 -0300
++++ grub-0.92/stage2/char_io.c 2002-06-17 21:19:23.000000000 -0300
+@@ -33,6 +33,8 @@
+ int max_lines = 24;
+ int count_lines = -1;
+ int use_pager = 1;
++#else
++#define putchar grub_putchar
+ #endif
+ void
+@@ -265,9 +267,9 @@
+   /* XXX: These should be defined in shared.h, but I leave these here,
+      until this code is freezed.  */
+-#define CMDLINE_WIDTH 78
+-#define CMDLINE_MARGIN        10
+-  
++  int CMDLINE_WIDTH = (view_x1 - view_x0) - 2;
++  int CMDLINE_MARGIN = 10;
++
+   int xpos, lpos, c, section;
+   /* The length of PROMPT.  */
+   int plen;
+@@ -316,7 +318,7 @@
+           {
+             int y = getxy () & 0xFF;
+             
+-            gotoxy (xpos, y);
++            gotoxy (xpos + view_x0, y);
+           }
+ # ifdef SUPPORT_SERIAL
+         else if (! (terminal & TERMINAL_DUMB) && (count > 4))
+@@ -328,7 +330,7 @@
+             int i;
+             
+             for (i = 0; i < count; i++)
+-              grub_putchar ('\b');
++              putchar ('\b');
+           }
+ # endif /* SUPPORT_SERIAL */
+       }
+@@ -354,7 +356,7 @@
+           {
+             int y = getxy () & 0xFF;
+             
+-            gotoxy (xpos, y);
++            gotoxy (xpos + view_x0, y);
+           }
+ # ifdef SUPPORT_SERIAL
+         else if (! (terminal & TERMINAL_DUMB) && (count > 4))
+@@ -368,9 +370,9 @@
+             for (i = lpos - count; i < lpos; i++)
+               {
+                 if (! echo_char)
+-                  grub_putchar (buf[i]);
++                  putchar (buf[i]);
+                 else
+-                  grub_putchar (echo_char);
++                  putchar (echo_char);
+               }
+           }
+ # endif /* SUPPORT_SERIAL */
+@@ -398,7 +400,7 @@
+         /* From the start to the end.  */
+         len = CMDLINE_WIDTH;
+         pos = 0;
+-        grub_putchar ('\r');
++        putchar ('\r');
+         /* If SECTION is the first section, print the prompt, otherwise,
+            print `<'.  */
+@@ -410,7 +412,7 @@
+           }
+         else
+           {
+-            grub_putchar ('<');
++            putchar ('<');
+             len--;
+             pos++;
+           }
+@@ -446,9 +448,9 @@
+       for (i = start; i < start + len && i < llen; i++)
+       {
+         if (! echo_char)
+-          grub_putchar (buf[i]);
++          putchar (buf[i]);
+         else
+-          grub_putchar (echo_char);
++          putchar (echo_char);
+         pos++;
+       }
+@@ -467,9 +469,9 @@
+          if (pos == CMDLINE_WIDTH)
+            {
+              if (start + len < llen)
+-               grub_putchar ('>');
++               putchar ('>');
+              else
+-               grub_putchar (' ');
++               putchar (' ');
+              
+              pos++;
+            }
+@@ -483,7 +485,7 @@
+            {
+              int y = getxy () & 0xFF;
+              
+-             gotoxy (xpos, y);
++             gotoxy (xpos + view_x0, y);
+            }
+ # ifdef SUPPORT_SERIAL      
+          else if (! (terminal & TERMINAL_SERIAL) && (pos - xpos > 4))
+@@ -493,7 +495,7 @@
+          else
+            {
+              for (i = 0; i < pos - xpos; i++)
+-               grub_putchar ('\b');
++               putchar ('\b');
+            }
+ # endif /* SUPPORT_SERIAL */
+        }
+@@ -503,7 +505,7 @@
+   void cl_init (void)
+     {
+       /* Distinguish us from other lines and error messages!  */
+-      grub_putchar ('\n');
++      putchar ('\n');
+       /* Print full line and set position here.  */
+       cl_refresh (1, 0);
+@@ -634,7 +636,7 @@
+                       /* There are more than one candidates, so print
+                          the list.  */
+-                      grub_putchar ('\n');
++                      putchar ('\n');
+                       /* Enable the auto fill mode temporarily.  */
+                       auto_fill = 1;
+                       print_completions (is_filename, 0);
+@@ -776,7 +778,7 @@
+       }
+     }
+-  grub_putchar ('\n');
++  putchar ('\n');
+   /* If ECHO_CHAR is NUL, remove the leading spaces.  */
+   lpos = 0;
+@@ -1121,8 +1123,8 @@
+   else if (c >= ' ' && c <= '~')
+     {
+       /* Fold a line only if AUTO_FILL is true.  */
+-      if (auto_fill && col >= 79)
+-      grub_putchar ('\n');
++      if (auto_fill && col >= view_x1 - view_x0)
++      putchar ('\n');
+       col++;
+     }
+@@ -1173,7 +1175,7 @@
+ #ifndef STAGE1_5
+ void
+-gotoxy (int x, int y)
++grub_gotoxy (int x, int y)
+ {
+   if (terminal & TERMINAL_CONSOLE)
+     console_gotoxy (x, y);
+@@ -1197,7 +1199,7 @@
+ #endif /* SUPPORT_SERIAL */
+ int
+-getxy (void)
++grub_getxy (void)
+ {
+   int ret = 0;
+   
+@@ -1302,7 +1304,7 @@
+ #endif /* SUPPORT_SERIAL */
+ void
+-cls (void)
++grub_cls (void)
+ {
+   if (terminal & TERMINAL_CONSOLE)
+     console_cls ();
+@@ -1330,7 +1332,7 @@
+ #endif /* SUPPORT_SERIAL */
+ void
+-set_attrib (int attr)
++grub_set_attrib (int attr)
+ {
+ #ifdef SUPPORT_HERCULES
+   if (terminal & TERMINAL_HERCULES)
+@@ -1445,6 +1447,8 @@
+       || (addr >= RAW_ADDR (0x100000)
+         && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
+     errnum = ERR_WONT_FIT;
++  else
++    errnum = 0;
+   return ! errnum;
+ }
+diff -ru grub-0.92.orig/stage2/cmdline.c grub-0.92/stage2/cmdline.c
+--- grub-0.92.orig/stage2/cmdline.c    2002-03-24 09:28:54.000000000 -0300
++++ grub-0.92/stage2/cmdline.c 2002-06-17 21:19:23.000000000 -0300
+@@ -125,7 +125,7 @@
+   init_page ();
+ #ifdef SUPPORT_DISKLESS
+   print_network_configuration ();
+-  grub_putchar ('\n');
++  putchar ('\n');
+ #endif
+   print_cmdline_message (forever);
+diff -ru grub-0.92.orig/stage2/disk_io.c grub-0.92/stage2/disk_io.c
+--- grub-0.92.orig/stage2/disk_io.c    2001-11-28 16:43:56.000000000 -0200
++++ grub-0.92/stage2/disk_io.c 2002-06-17 21:19:23.000000000 -0300
+@@ -1267,7 +1267,7 @@
+       }
+       if (! is_completion)
+-      grub_putchar ('\n');
++      putchar ('\n');
+       
+       print_error ();
+       do_completion = 0;
+@@ -1334,7 +1334,7 @@
+               }
+             if (! is_completion)
+-              grub_putchar ('\n');
++              putchar ('\n');
+           }
+         else
+           {
+@@ -1408,7 +1408,7 @@
+           }
+         
+         if (! is_completion)
+-          grub_putchar ('\n');
++          putchar ('\n');
+       }
+       else
+       errnum = ERR_BAD_FILENAME;
+diff -ru grub-0.92.orig/stage2/shared.h grub-0.92/stage2/shared.h
+--- grub-0.92.orig/stage2/shared.h     2002-03-25 18:43:55.000000000 -0300
++++ grub-0.92/stage2/shared.h  2002-06-17 21:19:23.000000000 -0300
+@@ -368,7 +368,9 @@
+ #define printf grub_printf
+ #define sprintf grub_sprintf
+ #undef putchar
+-#define putchar grub_putchar
++#ifdef GRUB_UTIL
++ #define putchar grub_putchar
++#endif
+ #define strncat grub_strncat
+ #define strstr grub_strstr
+ #define memcmp grub_memcmp
+@@ -383,6 +385,9 @@
+ /*
+  *  Below this should be ONLY defines and other constructs for C code.
+  */
++#ifdef VGA16
++#define VIDEO         0xA0000
++#endif
+ /* multiboot stuff */
+@@ -779,26 +784,26 @@
+ int currticks (void);
+ /* Clear the screen. */
+-void cls (void);
++void grub_cls (void);
+ /* The console part of cls.  */
+ void console_cls (void);
+ #ifndef GRUB_UTIL
+ /* Turn off cursor. */
+-void nocursor (void);
++void grub_nocursor (void);
+ #endif
+ /* Get the current cursor position (where 0,0 is the top left hand
+    corner of the screen).  Returns packed values, (RET >> 8) is x,
+    (RET & 0xff) is y. */
+-int getxy (void);
++int grub_getxy (void);
+ /* The console part of getxy.  */
+ int console_getxy (void);
+ /* Set the cursor position. */
+-void gotoxy (int x, int y);
++void grub_gotoxy (int x, int y);
+ /* The console part of gotoxy.  */
+ void console_gotoxy (int x, int y);
+@@ -826,11 +831,67 @@
+ /* Sets text mode character attribute at the cursor position.  See A_*
+    constants defined above. */
+-void set_attrib (int attr);
++void grub_set_attrib (int attr);
+ /* The console part of set_attrib.  */
+ void console_set_attrib (int attr);
++extern int view_x0, view_y0, view_x1, view_y1;
++#ifdef VGA16
++#define MAX_DISPLAYS  2
++
++#define cls()         (display->Cls ? (*display->Cls)() : 0)
++#define gotoxy(x, y)  (display->Gotoxy ? (*display->Gotoxy)(x, y) : 0)
++#define putchar(c)    (display->Putchar ? (*display->Putchar)(c) : 0)
++#define set_attrib(a) (display->SetAttrib ? (*display->SetAttrib)(a) : 0)
++#define getxy()               (display->Getxy ? (*display->Getxy)() : 0)
++#define nocursor()    (display->Nocursor ? (*display->Nocursor)() : 0)
++struct display_entry {
++    char *name;
++    int (*Begin)(void);
++    void (*End)(void);
++    void (*Cls)(void);
++    void (*Gotoxy)(int x, int y);
++    void (*Putchar)(int ch);
++    void (*SetAttrib)(int attr);
++    int (*Getxy)(void);
++    void (*Nocursor)(void);
++};
++struct display_entry display_entries[MAX_DISPLAYS + 1];
++extern struct display_entry *display;
++
++extern int vga_inited, foreground, background, shade, border;
++extern int display_idx, splash_set;
++extern short cursorX, cursorY, cursorWidth, cursorHeight;
++extern char cursorBuf[16], splashimage[64];
++
++int vga16_begin(void);
++void vga16_end(void);
++void vga16_cls(void);
++void vga16_gotoxy(int x, int y);
++void vga16_putchar(int ch);
++int vga16_getxy(void);
++void vga16_nocursor(void);
++void vga16_set_attrib(int attr);
++
++int read_image();
++void set_palette(int index, int red, int green, int blue);
++void *get_font(void);
++/* return previous video mode */
++int set_videomode(int mode);
++
++int hex(int);
++void set_int1c_handler();
++void unset_int1c_handler();
++void cursor(int state);
++#else
++#define cls           grub_cls
++#define gotoxy                grub_gotoxy
++#define set_attrib    grub_set_attrib
++#define getxy         grub_getxy
++#define nocursor      grub_nocursor
++#endif
++
+ /* Low-level disk I/O */
+ int get_diskinfo (int drive, struct geometry *geometry);
+ int biosdisk (int subfunc, int drive, struct geometry *geometry,
+@@ -840,6 +901,8 @@
+ /* Command-line interface functions. */
+ #ifndef STAGE1_5
++extern char chainboot[];
++
+ /* The flags for the builtins.  */
+ #define BUILTIN_CMDLINE               0x1     /* Run in the command-line.  */
+ #define BUILTIN_MENU          0x2     /* Run in the menu.  */
+@@ -1018,6 +1081,7 @@
+ /* Define flags for load_image here.  */
+ /* Don't pass a Linux's mem option automatically.  */
+ #define KERNEL_LOAD_NO_MEM_OPTION     (1 << 0)
++#define KERNEL_REALLY_LOAD            (1 << 16)
+ kernel_t load_image (char *kernel, char *arg, kernel_t suggested_type,
+                    unsigned long load_flags);
+diff -ru grub-0.92.orig/stage2/stage2.c grub-0.92/stage2/stage2.c
+--- grub-0.92.orig/stage2/stage2.c     2002-03-24 09:28:54.000000000 -0300
++++ grub-0.92/stage2/stage2.c  2002-06-17 21:19:23.000000000 -0300
+@@ -19,7 +19,13 @@
+ #include "shared.h"
++char chainboot[16];
++int view_x0 = 0, view_y0 = 0, view_x1 = 80, view_y1 = 25;
+ grub_jmp_buf restart_env;
++#ifdef VGA16
++int vga_disabled = 0, viewport_set = 0;
++int sx0, sy0, sx1, sy1;
++#endif
+ #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
+@@ -109,12 +115,12 @@
+     }
+ #endif /* SUPPORT_SERIAL */
+   
+-  gotoxy (77, y + 1);
++  gotoxy (view_x1 - 3, y + 1);
+   if (first)
+-    grub_putchar (disp_up);
++    putchar (disp_up);
+   else
+-    grub_putchar (' ');
++    putchar (' ');
+   menu_entries = get_entry (menu_entries, first, 0);
+@@ -122,13 +128,13 @@
+     {
+       int j = 0;
+-      gotoxy (3, y + i);
++      gotoxy (view_x0 + 3, y + i);
+       while (*menu_entries)
+       {
+-        if (j < 71)
++        if (j < (view_x1 - view_x0) - 9)
+           {
+-            grub_putchar (*menu_entries);
++            putchar (*menu_entries);
+             j++;
+           }
+@@ -138,16 +144,16 @@
+       if (*(menu_entries - 1))
+       menu_entries++;
+-      for (; j < 71; j++)
+-      grub_putchar (' ');
++      for (; j < (view_x1 - view_x0) - 9; j++)
++      putchar (' ');
+     }
+-  gotoxy (77, y + size);
++  gotoxy (view_x1 - 3, y + size);
+   if (*menu_entries)
+-    grub_putchar (disp_down);
++    putchar (disp_down);
+   else
+-    grub_putchar (' ');
++    putchar (' ');
+ }
+@@ -159,20 +165,20 @@
+ #define LINE_LENGTH 67
+   for (i = 0; i < LINE_LENGTH; i++)
+-    grub_putchar ('-');
+-  grub_putchar ('\n');
++    putchar ('-');
++  putchar ('\n');
+   for (i = first; i < size; i++)
+     {
+       /* grub's printf can't %02d so ... */
+       if (i < 10)
+-      grub_putchar (' ');
++      putchar (' ');
+       grub_printf ("%d: %s\n", i, get_entry (menu_entries, i, 0));
+     }
+   for (i = 0; i < LINE_LENGTH; i++)
+-    grub_putchar ('-');
+-  grub_putchar ('\n');
++    putchar ('-');
++  putchar ('\n');
+ #undef LINE_LENGTH
+ }
+@@ -211,10 +217,10 @@
+       )
+ # endif
+     {
+-      for (i = 0; i < 14; i++)
++      for (i = 0; i < 12; i++)
+       {
+         int j;
+-        for (j = 0; j < 75; j++)
++        for (j = view_x0; j < (view_x1 - view_x0) - 5; j++)
+           {
+             gotoxy (j + 1, i + y);
+             set_attrib (normal_color);
+@@ -223,33 +229,33 @@
+     }
+ #endif
+-  gotoxy (1, y);
++  gotoxy (view_x0 + 1, y);
+-  grub_putchar (disp_ul);
+-  for (i = 0; i < 73; i++)
+-    grub_putchar (disp_horiz);
+-  grub_putchar (disp_ur);
++  putchar (disp_ul);
++  for (i = 0; i < view_x1 - 7; i++)
++    putchar (disp_horiz);
++  putchar (disp_ur);
+   i = 1;
+   while (1)
+     {
+-      gotoxy (1, y + i);
++      gotoxy (view_x0 + 1, y + i);
+       if (i > size)
+       break;
+-      grub_putchar (disp_vert);
+-      gotoxy (75, y + i);
+-      grub_putchar (disp_vert);
++      putchar (disp_vert);
++      gotoxy (view_x1 - 5, y + i);
++      putchar (disp_vert);
+       i++;
+     }
+-  grub_putchar (disp_ll);
+-  for (i = 0; i < 73; i++)
+-    grub_putchar (disp_horiz);
+-  grub_putchar (disp_lr);
++  putchar (disp_ll);
++  for (i = view_x0; i < view_x1 - 7; i++)
++    putchar (disp_horiz);
++  putchar (disp_lr);
+ }
+ static void
+@@ -261,27 +267,27 @@
+   if (terminal & TERMINAL_SERIAL)
+     {
+       menu_entries = get_entry (menu_entries, entryno, 0);
+-      gotoxy (2, y);
+-      grub_putchar (' ');
+-      for (x = 3; x < 75; x++)
++      gotoxy (view_x0 + 2, y);
++      putchar (' ');
++      for (x = view_x0 + 3; x < view_x1 - 5; x++)
+       {
+-        if (*menu_entries && x < 71)
+-          grub_putchar (*menu_entries++);
++        if (*menu_entries && x < view_x1 - 9)
++          putchar (*menu_entries++);
+         else
+-          grub_putchar (' ');
++          putchar (' ');
+       }
+     }
+   else
+ #endif /* SUPPORT_SERIAL */
+     {
+-      for (x = 2; x < 75; x++)
++      for (x = view_x0 + 2; x < view_x1 - 5; x++)
+       {
+         gotoxy (x, y);
+         set_attrib (attr);
+       }
+     }
+-  gotoxy (74, y);
++  gotoxy (view_x1 - 6, y);
+ }
+ /* Set the attribute of the line Y to normal state.  */
+@@ -320,6 +326,7 @@
+ run_menu (char *menu_entries, char *config_entries, int num_entries,
+         char *heap, int entryno)
+ {
++  int timeout = 1;
+   int c, time1, time2 = -1, first_entry = 0;
+   char *cur_entry = 0;
+   int disp_up = DISP_UP;
+@@ -399,7 +406,7 @@
+ #endif /* ! GRUB_UTIL */
+       if (! (terminal & TERMINAL_DUMB))      
+-        print_border (3, 12);
++        print_border (3 + view_y0, 12);
+ #ifdef GRUB_UTIL
+       /* In the grub shell, always use ACS_*.  */
+@@ -455,10 +462,10 @@
+       grub_printf ("\n\nThe selected entry is %d ", entryno);
+       else
+       {
+-        print_entries (3, 12, first_entry, menu_entries);
++        print_entries (view_y0 + 3, 12, first_entry, menu_entries);
+         
+         /* highlight initial line */
+-        set_line_highlight (4 + entryno, first_entry + entryno, 
++        set_line_highlight (view_y0 + 4 + entryno, first_entry + entryno, 
+                             menu_entries);
+       }
+     }
+@@ -487,9 +494,9 @@
+                          entryno, grub_timeout);
+         else
+         {
+-            gotoxy (3, 22);
+-            printf ("The highlighted entry will be booted automatically in %d seconds.    ", grub_timeout);
+-            gotoxy (74, 4 + entryno);
++            gotoxy (view_x0 + 3, view_y1 - 2);
++            printf ("Select an option to install (%d seconds left).  ", grub_timeout);
++            gotoxy (view_x0 - 6, view_y0 + 4 + entryno);
+         }
+         
+         grub_timeout--;
+@@ -513,14 +520,15 @@
+         if (grub_timeout >= 0)
+           {
+             if (terminal & TERMINAL_DUMB)
+-              grub_putchar ('\r');
++              putchar ('\r');
+             else
+-              gotoxy (3, 22);
++              gotoxy (view_x0 + 3, view_y1 - 2);
+             printf ("                                                                    ");
+             grub_timeout = -1;
+             fallback_entry = -1;
+             if (! (terminal & TERMINAL_DUMB))
+-              gotoxy (74, 4 + entryno);
++              gotoxy (view_x1 - 6, view_x0 + 4 + entryno);
++            timeout = 0;
+           }
+         /* We told them above (at least in SUPPORT_SERIAL) to use
+@@ -536,17 +544,17 @@
+               {
+                 if (entryno > 0)
+                   {
+-                    set_line_normal (4 + entryno, first_entry + entryno,
++                    set_line_normal (view_y0 + 4 + entryno, first_entry + entryno,
+                                      menu_entries);
+                     entryno--;
+-                    set_line_highlight (4 + entryno, first_entry + entryno,
++                    set_line_highlight (view_y0 + 4 + entryno, first_entry + entryno,
+                                         menu_entries);
+                   }
+                 else if (first_entry > 0)
+                   {
+                     first_entry--;
+-                    print_entries (3, 12, first_entry, menu_entries);
+-                    set_line_highlight (4, first_entry + entryno, 
++                    print_entries (view_y0 + 3, 12, first_entry, menu_entries);
++                    set_line_highlight (view_y0 + 4, first_entry + entryno, 
+                                         menu_entries);
+                   }
+               }
+@@ -558,17 +566,17 @@
+             else
+               if (entryno < 11)
+                 {
+-                  set_line_normal (4 + entryno, first_entry + entryno,
++                  set_line_normal (view_y0 + 4 + entryno, first_entry + entryno,
+                                    menu_entries);
+                   entryno++;
+-                  set_line_highlight (4 + entryno, first_entry + entryno,
++                  set_line_highlight (view_y0 + 4 + entryno, first_entry + entryno,
+                                       menu_entries);
+                 }
+               else if (num_entries > 12 + first_entry)
+                 {
+                   first_entry++;
+-                  print_entries (3, 12, first_entry, menu_entries);
+-                  set_line_highlight (15, first_entry + entryno, menu_entries);
++                  print_entries (view_y0 + 3, 12, first_entry, menu_entries);
++                  set_line_highlight (view_y0 + 15, first_entry + entryno, menu_entries);
+                 }
+           }
+@@ -582,7 +590,7 @@
+             if ((c == 'd') || (c == 'o') || (c == 'O'))
+               {
+                 if (! (terminal & TERMINAL_DUMB))
+-                  set_line_normal (4 + entryno, first_entry + entryno,
++                  set_line_normal (view_y0 + 4 + entryno, first_entry + entryno,
+                                    menu_entries);
+                 /* insert after is almost exactly like insert before */
+@@ -640,8 +648,8 @@
+                   }
+                 else
+                   {
+-                    print_entries (3, 12, first_entry, menu_entries);
+-                    set_line_highlight (4 + entryno, first_entry + entryno,
++                    print_entries (view_y0 + 3, 12, first_entry, menu_entries);
++                    set_line_highlight (view_y0 + 4 + entryno, first_entry + entryno,
+                                         menu_entries);
+                   }
+               }
+@@ -664,7 +672,7 @@
+                 if (terminal & TERMINAL_DUMB)
+                   grub_printf ("\r                                    ");
+                 else
+-                  gotoxy (1, 21);
++                  gotoxy (view_x0 + 1, view_y1 - 3);
+                 /* Wipe out the previously entered password */
+                 memset (entered, 0, sizeof (entered));
+@@ -807,11 +815,26 @@
+  boot_entry:
+   /* Enable the auto fill mode.  */
+   auto_fill = 1;
+-  
+-  cls ();
++
++  if (timeout && *chainboot) {
++     errnum = 0;
++     if (root_func(chainboot, 0) == 0) {
++      /* If can set the new root device */
++      if (chainloader_func("+1", 0) == 0)
++          /* If can load the new boot */
++          boot_func("", 0);
++    }
++  }
+   while (1)
+     {
++      cls ();
++#ifdef VGA16
++      if (display->End)
++      (*display->End)();
++      display = &display_entries[0];
++#endif
++
+       if (config_entries)
+       printf ("  Booting \'%s\'\n\n",
+               get_entry (menu_entries, first_entry + entryno, 0));
+@@ -840,6 +863,16 @@
+       break;
+     }
++#ifdef VGA16
++      if (display_idx >= 0)
++      display = &display_entries[display_idx];
++      else if (!vga_disabled)
++      display = &display_entries[1];
++
++      if (!display->Begin || !(*display->Begin)())
++      display = &display_entries[0];
++#endif
++
+   show_menu = 1;
+   goto restart;
+ }
+@@ -904,6 +937,560 @@
+   return pos;
+ }
++#ifdef VGA16
++struct display_entry display_entries[MAX_DISPLAYS + 1] = {
++    {"text", 0, 0, grub_cls, grub_gotoxy, grub_putchar, grub_set_attrib,
++     grub_getxy, grub_nocursor},
++    {"vga16",
++     vga16_begin, vga16_end, vga16_cls, vga16_gotoxy, vga16_putchar,
++     vga16_set_attrib, vga16_getxy, vga16_nocursor},
++    {0, 0, 0, 0, 0, 0, 0, 0, 0}
++};
++struct display_entry *display;
++int display_idx = -1;
++
++/* default vga palette */
++char vga16pal[16][3] = {
++    { 0,  0,  0},
++    { 0,  0, 42},
++    { 0, 42,  0},
++    { 0, 42, 42},
++    {42,  0,  0},
++    {42,  0, 42},
++    {42, 21,  0},
++    {42, 42, 42},
++    {21, 21, 21},
++    {21, 21, 63},
++    {21, 63, 21},
++    {21, 63, 63},
++    {63, 21, 21},
++    {63, 21, 63},
++    {63, 63, 21},
++    {63, 63, 63},
++};
++
++int fontx, fonty;
++unsigned char *font8x16;
++int saved_videomode, no_scroll = 0, no_cursor = 0, shade = 1, vga_inited = 0;
++unsigned short text[80 * 30];
++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
++int splash_set;
++char splashimage[64];
++#define VSHADOW VSHADOW1
++unsigned char VSHADOW1[38400];
++unsigned char VSHADOW2[38400];
++unsigned char VSHADOW4[38400];
++unsigned char VSHADOW8[38400];
++
++static inline void
++outb(unsigned short port, unsigned char val)
++{
++    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
++}
++
++static void
++ModeReg(int value)
++{
++    outb(0x3ce, 5);
++    outb(0x3cf, value);
++}
++
++static void
++MapMask(int value)
++{
++    outb(0x3c4, 2);
++    outb(0x3c5, value);
++}
++
++/* set/reset register */
++static void
++SetRes(int value)
++{
++    outb(0x3ce, 0);
++    outb(0x3cf, value);
++}
++
++/* enable set/reset register */
++static void
++ESetRes(int value)
++{
++    outb(0x3ce, 1);
++    outb(0x3cf, value);
++}
++
++static void
++ReadMap(int value)
++{
++    outb(0x3ce, 4);
++    outb(0x3cf, value);
++}
++
++/* bit mask register */
++static void
++BitMask(int value)
++{
++    outb(0x3ce, 8);
++    outb(0x3cf, value);
++}
++
++void
++grub_memcpy(void *dest, const void *src, int len)
++{
++    int i;
++    register char *d = (char*)dest, *s = (char*)src;
++
++    for (i = 0; i < len; i++)
++      d[i] = s[i];
++}
++
++int
++hex(int v)
++{
++    if (v >= 'A' && v <= 'F')
++      return (v - 'A' + 10);
++    if (v >= 'a' && v <= 'f')
++      return (v - 'a' + 10);
++    return (v - '0');
++}
++
++static void
++SetXY(int col, int row)
++{
++    if (col >= view_x0 && col < view_x1) {
++      fontx = col;
++      cursorX = col << 3;
++    }
++    if (row >= view_y0 && row < view_y1) {
++      fonty = row;
++      cursorY = row << 4;
++    }
++}
++
++void
++cursor(int set)
++{
++    unsigned char *pat, *mem, *ptr, chr[16 << 2];
++    int i, ch, invert, offset;
++
++    if (set && (no_cursor || no_scroll))
++      return;
++
++    offset = cursorY * 80 + fontx;
++    ch = text[fonty * 80 + fontx] & 0xff;
++    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
++    pat = font8x16 + (ch << 4);
++
++    mem = (unsigned char*)VIDEO + offset;
++
++    if (!set) {
++      for (i = 0; i < 16; i++) {
++          unsigned char mask = pat[i];
++
++          if (!invert) {
++              chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
++              chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
++              chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
++              chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
++
++              if (shade) {
++                  if (ch == DISP_VERT || ch == DISP_LL ||
++                      ch == DISP_UR || ch == DISP_LR) {
++                      unsigned char pmask = ~(pat[i] >> 1);
++
++                      chr[i     ] &= pmask;
++                      chr[16 + i] &= pmask;
++                      chr[32 + i] &= pmask;
++                      chr[48 + i] &= pmask;
++                  }
++                  if (i > 0 && ch != DISP_VERT) {
++                      unsigned char pmask = ~(pat[i - 1] >> 1);
++
++                      chr[i     ] &= pmask;
++                      chr[16 + i] &= pmask;
++                      chr[32 + i] &= pmask;
++                      chr[48 + i] &= pmask;
++                      if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
++                          pmask = ~pat[i - 1];
++
++                          chr[i     ] &= pmask;
++                          chr[16 + i] &= pmask;
++                          chr[32 + i] &= pmask;
++                          chr[48 + i] &= pmask;
++                      }
++                  }
++              }
++              chr[i     ] |= mask;
++              chr[16 + i] |= mask;
++              chr[32 + i] |= mask;
++              chr[48 + i] |= mask;
++
++              offset += 80;
++          }
++          else {
++              chr[i     ] = mask;
++              chr[16 + i] = mask;
++              chr[32 + i] = mask;
++              chr[48 + i] = mask;
++          }
++      }
++    }
++    else {
++      MapMask(15);
++      ptr = mem;
++      for (i = 0; i < 16; i++, ptr += 80) {
++          cursorBuf[i] = pat[i];
++          *ptr = ~pat[i];
++      }
++      return;
++    }
++
++    offset = 0;
++    for (i = 1; i < 16; i <<= 1, offset += 16) {
++      int j;
++
++      MapMask(i);
++      ptr = mem;
++      for (j = 0; j < 16; j++, ptr += 80)
++          *ptr = chr[j + offset];
++    }
++
++    MapMask(15);
++}
++
++int
++read_image(void)
++{
++    char buf[32], pal[16];
++    unsigned char c, base, mask, *s1, *s2, *s4, *s8;
++    unsigned i, len, idx, colors, x, y, width, height;
++
++    if (!grub_open(splashimage))
++      return (0);
++
++    /* read header */
++    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
++      grub_close();
++      return (0);
++    }
++
++    /* parse info */
++    while (grub_read(&c, 1)) {
++      if (c == '"')
++          break;
++    }
++
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++      ;
++
++    i = 0;
++    width = c - '0';
++    while (grub_read(&c, 1)) {
++      if (c >= '0' && c <= '9')
++          width = width * 10 + c - '0';
++      else
++          break;
++    }
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++      ;
++
++    height = c - '0';
++    while (grub_read(&c, 1)) {
++      if (c >= '0' && c <= '9')
++          height = height * 10 + c - '0';
++      else
++          break;
++    }
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++      ;
++
++    colors = c - '0';
++    while (grub_read(&c, 1)) {
++      if (c >= '0' && c <= '9')
++          colors = colors * 10 + c - '0';
++      else
++          break;
++    }
++
++    base = 0;
++    while (grub_read(&c, 1) && c != '"')
++      ;
++
++    /* palette */
++    for (i = 0, idx = 1; i < colors; i++) {
++      len = 0;
++
++      while (grub_read(&c, 1) && c != '"')
++          ;
++      grub_read(&c, 1);       /* char */
++      base = c;
++      grub_read(buf, 4);      /* \t c # */
++
++      while (grub_read(&c, 1) && c != '"') {
++          if (len < sizeof(buf))
++              buf[len++] = c;
++      }
++
++      if (len == 6 && idx < 15) {
++          int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
++          int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
++          int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
++
++          pal[idx] = base;
++          set_palette(idx, r, g, b);
++          ++idx;
++      }
++    }
++
++    x = y = len = 0;
++
++    s1 = (unsigned char*)VSHADOW1;
++    s2 = (unsigned char*)VSHADOW2;
++    s4 = (unsigned char*)VSHADOW4;
++    s8 = (unsigned char*)VSHADOW8;
++
++    for (i = 0; i < 38400; i++)
++      s1[i] = s2[i] = s4[i] = s8[i] = 0;
++
++    /* parse xpm data */
++    while (y < height) {
++      while (1) {
++          if (!grub_read(&c, 1)) {
++              grub_close();
++              return (0);
++          }
++          if (c == '"')
++              break;
++      }
++
++      while (grub_read(&c, 1) && c != '"') {
++          for (i = 1; i < 15; i++)
++              if (pal[i] == c) {
++                  c = i;
++                  break;
++              }
++
++          mask = 0x80 >> (x & 7);
++          if (c & 1)
++              s1[len + (x >> 3)] |= mask;
++          if (c & 2)
++              s2[len + (x >> 3)] |= mask;
++          if (c & 4)
++              s4[len + (x >> 3)] |= mask;
++          if (c & 8)
++              s8[len + (x >> 3)] |= mask;
++
++          if (++x >= 640) {
++              x = 0;
++
++              if (y < 480)
++                  len += 80;
++              ++y;
++          }
++      }
++    }
++
++    grub_close();
++
++    set_palette(0, (background >> 16), (background >> 8) & 63, background & 63);
++    set_palette(15, (foreground >> 16), (foreground >> 8) & 63, foreground & 63);
++
++    set_palette(0x11, (border >> 16), (border >> 8) & 63, border & 63);
++
++    return (1);
++}
++
++int
++vga16_begin(void)
++{
++    if (vga_inited)
++      return (1);
++
++    if (!*splashimage)
++      grub_strcpy(splashimage, "/boot/grub/splash.xpm");
++
++    saved_videomode = set_videomode(0x12);
++    if (!read_image()) {
++      set_videomode(saved_videomode);
++      return (0);
++    }
++
++    font8x16 = (unsigned char*)get_font();
++
++    cursorWidth = 8;
++    cursorHeight = 16;
++
++    set_int1c_handler();
++
++    view_x0 = sx0;
++    view_y0 = sy0;
++    view_x1 = sx1;
++    view_y1 = sy1;
++
++    return (vga_inited = 1);
++}
++
++void
++vga16_end(void)
++{
++    if (vga_inited) {
++      unset_int1c_handler();
++      set_videomode(saved_videomode);
++      vga_inited = 0;
++      no_cursor = 0;
++    }
++
++    sx0 = view_x0;
++    sy0 = view_y0;
++    sx1 = view_x1;
++    sy1 = view_y1;
++    view_x0 = 0;
++    view_x1 = 80;
++    view_y0 = 0;
++    view_y1 = 25;
++}
++
++void
++vga16_cls(void)
++{
++    int i;
++    unsigned char *mem, *s1, *s2, *s4, *s8;
++
++    SetXY(view_x0, view_y0);
++
++    mem = (unsigned char*)VIDEO;
++    s1 = (unsigned char*)VSHADOW1;
++    s2 = (unsigned char*)VSHADOW2;
++    s4 = (unsigned char*)VSHADOW4;
++    s8 = (unsigned char*)VSHADOW8;
++
++    for (i = 0; i < 80 * 30; i++)
++      text[i] = ' ';
++
++    BitMask(0xff);
++
++    /* plano 1 */
++    MapMask(1);
++    grub_memcpy(mem, s1, 38400);
++
++    /* plano 2 */
++    MapMask(2);
++    grub_memcpy(mem, s2, 38400);
++
++    /* plano 3 */
++    MapMask(4);
++    grub_memcpy(mem, s4, 38400);
++
++    /* plano 4 */
++    MapMask(8);
++    grub_memcpy(mem, s8, 38400);
++
++    MapMask(15);
++
++    if (no_cursor) {
++      no_cursor = 0;
++      set_int1c_handler();
++    }
++}
++
++void
++vga16_gotoxy(int x, int y)
++{
++    cursor(0);
++
++    SetXY(x, y);
++
++    cursor(1);
++}
++
++static void
++scroll(void)
++{
++    int i, j;
++
++    if (no_scroll)
++      return;
++
++    no_scroll = 1;
++
++    for (j = view_y0 + 1; j < view_y1; j++) {
++      gotoxy(view_x0, j - 1);
++      for (i = view_x0; i < view_x1; i++)
++          putchar(text[j * 80 + i]);
++    }
++
++    gotoxy(view_x0, view_y1 - 1);
++    for (i = view_x0; i < view_x1; i++)
++      putchar(' ');
++
++    SetXY(view_x0, view_y1 - 1);
++
++    no_scroll = 0;
++}
++
++void
++vga16_putchar(int ch)
++{
++    ch &= 0xff;
++
++    cursor(0);
++
++    if (ch == '\n') {
++      SetXY(view_x0, fonty);
++      if (fonty + 1 < view_y1)
++          SetXY(view_x0, fonty + 1);
++      else
++          scroll();
++      cursor(1);
++      return;
++    }
++    else if (ch == '\r') {
++      SetXY(view_x0, fonty);
++      cursor(1);
++      return;
++    }
++
++    text[fonty * 80 + fontx] = ch;
++
++    cursor(0);
++
++    if ((fontx + 1) >= view_x1) {
++      SetXY(view_x0, fonty);
++      if (fonty + 1 < view_y1)
++          SetXY(view_x0, fonty + 1);
++      else
++          scroll();
++    }
++    else
++      SetXY(fontx + 1, fonty);
++
++    cursor(1);
++}
++
++int
++vga16_getxy()
++{
++    return ((fontx << 8) | fonty);
++}
++
++void
++vga16_nocursor()
++{
++    if (!no_cursor) {
++      no_cursor = 1;
++      unset_int1c_handler();
++      cursor(0);
++    }
++}
++
++void
++vga16_set_attrib(int attrib)
++{
++    text[fonty * 80 + fontx] &= 0x00ff;
++    if (attrib & 0xf0)
++      text[fonty * 80 + fontx] |= 0x100;
++    cursor(0);
++}
++#endif
+ /* This is the starting function in C.  */
+ void
+@@ -924,7 +1511,15 @@
+       menu_entries = (char *) MENU_BUF;
+       init_config ();
+     }
+-      
++
++#ifdef VGA16
++  /* Make sure it points to a valid entry */
++  display = &display_entries[0];
++
++  if (ASCII_CHAR(checkkey()) == 0x1b)
++    vga_disabled = 1;
++#endif
++
+   /* Initialize the environment for restarting Stage 2.  */
+   grub_setjmp (restart_env);
+   
+@@ -1069,6 +1664,29 @@
+         while (is_preset);
+       }
++#ifdef VGA16
++      if (display_idx >= 0)
++      display = &display_entries[display_idx];
++      else if (!vga_disabled) {
++      display = &display_entries[1];
++      }
++      if (!viewport_set)
++      view_y1 = 30;
++      sx0 = view_x0;
++      sy0 = view_y0;
++      sx1 = view_x1;
++      sy1 = view_y1;
++
++      if (!display->Begin || !(*display->Begin)())
++      display = &display_entries[0];
++
++      if (!vga_inited) {
++      sx0 = sy0 = view_x0 = view_y0 = 0;
++      sx1 = view_x1 = 80;
++      sy1 = view_y1 = 25;       
++      }
++#endif
++
+       if (! num_entries)
+       {
+         /* If no acceptable config file, goto command-line, starting
+diff -ru grub-0.92.orig/stage2/builtins.c grub-0.92/stage2/builtins.c
+--- grub-0.92.orig/stage2/builtins.c   2002-06-25 17:58:03.000000000 -0300
++++ grub-0.92/stage2/builtins.c        2002-06-25 17:36:23.000000000 -0300
+@@ -4856,6 +4856,7 @@
+     view_y0 = y0;
+     view_x1 = x1;
+     view_y1 = y1;
++    max_lines = view_y1 - view_y0;
+     if (flags == BUILTIN_CMDLINE && vga_inited) {
+       display->End();
+Only in grub-0.92/stage2: builtins.c~
+diff -ru grub-0.92.orig/stage2/char_io.c grub-0.92/stage2/char_io.c
+--- grub-0.92.orig/stage2/char_io.c    2002-06-25 17:58:03.000000000 -0300
++++ grub-0.92/stage2/char_io.c 2002-06-25 17:53:31.000000000 -0300
+@@ -460,7 +460,7 @@
+          /* Fill up the rest of the line with spaces.  */
+          for (; i < start + len; i++)
+            {
+-             grub_putchar (' ');
++             putchar (' ');
+              pos++;
+            }
+         
+diff -ru grub-0.92.orig/stage2/stage2.c grub-0.92/stage2/stage2.c
+--- grub-0.92.orig/stage2/stage2.c     2002-06-25 17:58:03.000000000 -0300
++++ grub-0.92/stage2/stage2.c  2002-06-25 18:07:39.000000000 -0300
+@@ -217,10 +217,10 @@
+       )
+ # endif
+     {
+-      for (i = 0; i < 12; i++)
++      for (i = 0; i < 14; i++)
+       {
+         int j;
+-        for (j = view_x0; j < (view_x1 - view_x0) - 5; j++)
++        for (j = view_x0; j < view_x1 - 5; j++)
+           {
+             gotoxy (j + 1, i + y);
+             set_attrib (normal_color);
+@@ -232,7 +232,7 @@
+   gotoxy (view_x0 + 1, y);
+   putchar (disp_ul);
+-  for (i = 0; i < view_x1 - 7; i++)
++  for (i = view_x0; i < view_x1 - 7; i++)
+     putchar (disp_horiz);
+   putchar (disp_ur);
+@@ -1448,6 +1448,11 @@
+       cursor(1);
+       return;
+     }
++    else if (ch == '\b') {
++      if (fontx < view_x0)
++          SetXY(fontx - 1, fonty);
++      return;
++    }
+     text[fonty * 80 + fontx] = ch;
This page took 0.13284 seconds and 4 git commands to generate.