/[grub]/grub2/video/i386/pc/vbe.c
ViewVC logotype

Diff of /grub2/video/i386/pc/vbe.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by chaac, Tue Aug 16 18:34:17 2005 UTC revision 1.3 by okuji, Fri Aug 19 00:32:01 2005 UTC
# Line 71  grub_err_t Line 71  grub_err_t
71  grub_vbe_probe (struct grub_vbe_info_block *info_block)  grub_vbe_probe (struct grub_vbe_info_block *info_block)
72  {  {
73    struct grub_vbe_info_block *vbe_ib;    struct grub_vbe_info_block *vbe_ib;
74    grub_uint32_t rc;    grub_vbe_status_t status;
75      
76    /* Clear caller's controller info block.  */    /* Clear caller's controller info block.  */
77    if (info_block != 0)    if (info_block)
78      {      grub_memset (info_block, 0, sizeof (*info_block));
       grub_memset (info_block, 0, sizeof(struct grub_vbe_info_block));  
     }  
79    
80    /* Do not probe more than one time.  */    /* Do not probe more than one time, if not necessary.  */
81    if (vbe_detected != -1)    if (vbe_detected == -1 || info_block)
82      {      {
83        if (vbe_detected == 1)        /* Clear old copy of controller info block.  */
84          {        grub_memset (&controller_info, 0, sizeof (controller_info));
85            /* Make copy of controller info block to caller.  */  
86            if (info_block != 0)        /* Mark VESA BIOS extension as undetected.  */
87              {        vbe_detected = 0;
88                grub_memcpy (info_block,        
89                             &controller_info,        /* Use low memory scratch area as temporary storage
90                             sizeof(struct grub_vbe_info_block));           for VESA BIOS call.  */
91              }        vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
92            return GRUB_ERR_NONE;        
93          }        /* Prepare info block.  */
94        else        grub_memset (vbe_ib, 0, sizeof (*vbe_ib));
95          
96          vbe_ib->signature[0] = 'V';
97          vbe_ib->signature[1] = 'B';
98          vbe_ib->signature[2] = 'E';
99          vbe_ib->signature[3] = '2';
100          
101          /* Try to get controller info block.  */
102          status = grub_vbe_get_controller_info (vbe_ib);
103          if (status == 0x004F)
104          {          {
105            return GRUB_ERR_BAD_DEVICE;            /* Copy it for later usage.  */
106              grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));
107              
108              /* Mark VESA BIOS extension as detected.  */
109              vbe_detected = 1;
110          }          }
111      }      }
112    
113    /* Clear old copy of controller info block.  */    if (! vbe_detected)
114    grub_memset (&controller_info, 0, sizeof(struct grub_vbe_info_block));      return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found");
   
   /* 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;  
     }  
115    
116    /* Copy it for later usage.  */    /* Make copy of controller info block to caller.  */
117    grub_memcpy (&controller_info,    if (info_block)
118                 vbe_ib,      grub_memcpy (info_block, &controller_info, sizeof (*info_block));
                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;  
119    
120    return GRUB_ERR_NONE;    return GRUB_ERR_NONE;
121  }  }
# Line 143  grub_err_t Line 124  grub_err_t
124  grub_vbe_set_video_mode (grub_uint32_t mode,  grub_vbe_set_video_mode (grub_uint32_t mode,
125                           struct grub_vbe_mode_info_block *mode_info)                           struct grub_vbe_mode_info_block *mode_info)
126  {  {
127    grub_uint32_t rc;    grub_vbe_status_t status;
128      grub_uint32_t old_mode;
129    /* If grub_vesafb_probe has not been called or no VBE, abort.  */    
130    if (vbe_detected == 0)    /* Make sure that VBE is supported.  */
131      {    if (grub_vbe_probe (0) != GRUB_ERR_NONE)
132        return GRUB_ERR_BAD_DEVICE;      return grub_errno;
     }  
133    
134    /* Try to get mode info.  */    /* Try to get mode info.  */
135    rc = grub_vbe_get_video_mode_info (mode, &active_mode_info);    if (grub_vbe_get_video_mode_info (mode, &active_mode_info) != GRUB_ERR_NONE)
136    if (rc != GRUB_ERR_NONE)      return grub_errno;
     {  
       return rc;  
     }  
137    
138    /* For all VESA BIOS modes, force linear frame buffer.  */    /* For all VESA BIOS modes, force linear frame buffer.  */
139    if (mode >= 0x100)    if (mode >= 0x100)
# Line 165  grub_vbe_set_video_mode (grub_uint32_t m Line 142  grub_vbe_set_video_mode (grub_uint32_t m
142        mode |= 1 << 14;        mode |= 1 << 14;
143    
144        /* Determine frame buffer pixel format.  */        /* Determine frame buffer pixel format.  */
145        switch(active_mode_info.memory_model)        switch (active_mode_info.memory_model)
146          {          {
147          case 0x04:          case 0x04:
148            index_color_mode = 1;            index_color_mode = 1;
149            break;            break;
150              
151          case 0x06:          case 0x06:
152            index_color_mode = 0;            index_color_mode = 0;
153            break;            break;
154              
155          default:          default:
156            return GRUB_ERR_BAD_DEVICE;            return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
157                                 "unsupported pixel format 0x%x",
158                                 active_mode_info.memory_model);
159          }          }
160      }      }
161    
162      /* Get current mode.  */
163      if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE)
164        return grub_errno;
165      
166    /* Try to set video mode.  */    /* Try to set video mode.  */
167    rc = grub_vbe_set_mode (mode, 0);    status = grub_vbe_set_mode (mode, 0);
168    if (rc != 0x004F)    if (status != 0x004F)
169      {      return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", mode);
       return GRUB_ERR_BAD_DEVICE;  
     }  
170    
171    /* Save information for later usage.  */    /* Save information for later usage.  */
172    active_mode = mode;    active_mode = mode;
# Line 193  grub_vbe_set_video_mode (grub_uint32_t m Line 174  grub_vbe_set_video_mode (grub_uint32_t m
174    if (mode < 0x100)    if (mode < 0x100)
175      {      {
176        /* If this is not a VESA mode, guess address.  */        /* If this is not a VESA mode, guess address.  */
177        framebuffer = (grub_uint8_t *)0xA0000;        framebuffer = (grub_uint8_t *) 0xA0000;
178        index_color_mode = 1;        index_color_mode = 1;
179      }      }
180    else    else
181      {      {
182        framebuffer = (grub_uint8_t *)active_mode_info.phys_base_addr;        framebuffer = (grub_uint8_t *) active_mode_info.phys_base_addr;
183    
184        if (controller_info.version >= 0x300)        if (controller_info.version >= 0x300)
185          {          bytes_per_scan_line = active_mode_info.lin_bytes_per_scan_line;
           bytes_per_scan_line = active_mode_info.lin_bytes_per_scan_line;  
         }  
186        else        else
187          {          bytes_per_scan_line = active_mode_info.bytes_per_scan_line;
           bytes_per_scan_line = active_mode_info.bytes_per_scan_line;  
         }  
188      }      }
189    
190    /* If video mode is in indexed color, setup default VGA palette.  */    /* If video mode is in indexed color, setup default VGA palette.  */
191    if (index_color_mode != 0)    if (index_color_mode)
192      {      {
193        rc = grub_vbe_set_palette_data (16, 0, vga_colors);        struct grub_vbe_palette_data *palette
194        if (rc != 0x004F)          = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
195          {  
196            return GRUB_ERR_BAD_DEVICE;        /* Make sure that the BIOS can reach the palette.  */
197          }        grub_memcpy (palette, vga_colors, sizeof (vga_colors));
198          status = grub_vbe_set_palette_data (16, 0, palette);
199    
200          /* For now, ignore the status. Not sure if this is fatal.  */
201    #if 0
202          if (status != 0x004F)
203            {
204              grub_vbe_set_mode (old_mode, 0);
205              return grub_error (GRUB_ERR_BAD_DEVICE,
206                                 "cannot set the default VGA palette");
207            }
208    #endif
209      }      }
210    
211    /* Copy mode info for caller.  */    /* Copy mode info for caller.  */
212    if (mode_info != 0)    if (mode_info)
213      {      grub_memcpy (mode_info, &active_mode_info, sizeof (*mode_info));
       grub_memcpy (mode_info,  
                    &active_mode_info,  
                    sizeof(struct grub_vbe_mode_info_block));  
     }  
214    
215    return GRUB_ERR_NONE;    return GRUB_ERR_NONE;
216  }  }
# Line 234  grub_vbe_set_video_mode (grub_uint32_t m Line 218  grub_vbe_set_video_mode (grub_uint32_t m
218  grub_err_t  grub_err_t
219  grub_vbe_get_video_mode (grub_uint32_t *mode)  grub_vbe_get_video_mode (grub_uint32_t *mode)
220  {  {
221    grub_uint32_t rc;    grub_vbe_status_t status;
222    
223    /* If grub_vesafb_probe has not been called or no VBE, abort.  */    /* Make sure that VBE is supported.  */
224    if (vbe_detected == 0)    if (grub_vbe_probe (0) != GRUB_ERR_NONE)
225      {      return grub_errno;
       return GRUB_ERR_BAD_DEVICE;  
     }  
226    
227    /* Try to query current mode from VESA BIOS.  */    /* Try to query current mode from VESA BIOS.  */
228    rc = grub_vbe_get_mode (mode);    status = grub_vbe_get_mode (mode);
229    if (rc != 0x004F)    if (status != 0x004F)
230      {      return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode");
       return GRUB_ERR_BAD_DEVICE;  
     }  
231    
232    return GRUB_ERR_NONE;    return GRUB_ERR_NONE;
233  }  }
# Line 256  grub_err_t Line 236  grub_err_t
236  grub_vbe_get_video_mode_info (grub_uint32_t mode,  grub_vbe_get_video_mode_info (grub_uint32_t mode,
237                                struct grub_vbe_mode_info_block *mode_info)                                struct grub_vbe_mode_info_block *mode_info)
238  {  {
239    struct grub_vbe_mode_info_block *mi_tmp = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;    struct grub_vbe_mode_info_block *mi_tmp
240    grub_uint32_t rc;      = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
241      grub_vbe_status_t status;
242    /* If grub_vesafb_probe has not been called or no VBE, abort.  */  
243    if (vbe_detected == 0)    /* Make sure that VBE is supported.  */
244      {    if (grub_vbe_probe (0) != GRUB_ERR_NONE)
245        return GRUB_ERR_BAD_DEVICE;      return grub_errno;
     }  
246    
247    /* If mode is not VESA mode, skip mode info query.  */    /* If mode is not VESA mode, skip mode info query.  */
248    if (mode >= 0x100)    if (mode >= 0x100)
249      {      {
250        /* Try to get mode info from VESA BIOS.  */        /* Try to get mode info from VESA BIOS.  */
251        rc = grub_vbe_get_mode_info (mode, mi_tmp);        status = grub_vbe_get_mode_info (mode, mi_tmp);
252        if (rc != 0x004F)        if (status != 0x004F)
253          {          return grub_error (GRUB_ERR_BAD_DEVICE,
254            return GRUB_ERR_BAD_DEVICE;                             "cannot get information on the mode %x", mode);
         }  
255    
256        /* Make copy of mode info block.  */        /* Make copy of mode info block.  */
257        grub_memcpy (mode_info,        grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));
                    mi_tmp,  
                    sizeof(struct grub_vbe_mode_info_block));  
258      }      }
259    else    else
260      {      /* Just clear mode info block if it isn't a VESA mode.  */
261        /* Just clear mode info block if it isn't a VESA mode.  */      grub_memset (mode_info, 0, sizeof (*mode_info));
       grub_memset (mode_info,  
                    0,  
                    sizeof(struct grub_vbe_mode_info_block));  
     }  
262    
263    return GRUB_ERR_NONE;    return GRUB_ERR_NONE;
264  }  }
# Line 327  grub_vbe_set_pixel_rgb (grub_uint32_t x, Line 299  grub_vbe_set_pixel_rgb (grub_uint32_t x,
299        value |= blue << active_mode_info.blue_field_position;        value |= blue << active_mode_info.blue_field_position;
300      }      }
301    
302    if (active_mode_info.bits_per_pixel == 32)    switch (active_mode_info.bits_per_pixel)
303      {      {
304        grub_uint32_t *ptr = (grub_uint32_t *)(framebuffer      case 32:
305                                               + y * bytes_per_scan_line        {
306                                               + x * 4);          grub_uint32_t *ptr = (grub_uint32_t *) (framebuffer
307                                                    + y * bytes_per_scan_line
308                                                    + x * 4);
309            
310            *ptr = value;
311          }
312          break;
313          
314        case 24:
315          {
316            grub_uint8_t *ptr = (grub_uint8_t *) (framebuffer
317                                                  + y * bytes_per_scan_line
318                                                  + x * 3);
319            grub_uint8_t *ptr2 = (grub_uint8_t *) &value;
320            
321            ptr[0] = ptr2[0];
322            ptr[1] = ptr2[1];
323            ptr[2] = ptr2[2];
324          }
325          break;
326    
327        case 16:
328        case 15:
329          {
330            grub_uint16_t *ptr = (grub_uint16_t *) (framebuffer
331                                                    + y * bytes_per_scan_line
332                                                    + x * 2);
333            
334            *ptr = (grub_uint16_t) (value & 0xFFFF);
335          }
336          break;
337    
338        *ptr = value;      default:
339      }        break;
   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);  
340      }      }
341  }  }
342    
# Line 370  grub_vbe_set_pixel_index (grub_uint32_t Line 353  grub_vbe_set_pixel_index (grub_uint32_t
353    
354    if (index_color_mode == 1)    if (index_color_mode == 1)
355      {      {
356        grub_uint8_t *ptr = (grub_uint8_t *)(framebuffer        grub_uint8_t *ptr = (grub_uint8_t *) (framebuffer
357                                             + y * bytes_per_scan_line                                              + y * bytes_per_scan_line
358                                             + x);                                              + x);
359    
360        *ptr = color;        *ptr = color;
361      }      }
362    else    else
363      {      {
364        color &= 0x0F;        color &= 0x0F;
365          
366        if (color < 16)        if (color < 16)
367          {          {
368            grub_vbe_set_pixel_rgb (x,            grub_vbe_set_pixel_rgb (x,
# Line 396  grub_vbe_set_pixel_index (grub_uint32_t Line 379  grub_vbe_set_pixel_index (grub_uint32_t
379                                    0,                                    0,
380                                    0);                                    0);
381          }          }
382    }      }
383  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26