2  * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * The contents of this file constitute Original Code as defined in and 
   7  * are subject to the Apple Public Source License Version 1.1 (the 
   8  * "License").  You may not use this file except in compliance with the 
   9  * License.  Please obtain a copy of the License at 
  10  * http://www.apple.com/publicsource and read it before using this file. 
  12  * This Original Code and all software distributed under the License are 
  13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the 
  17  * License for the specific language governing rights and limitations 
  20  * @APPLE_LICENSE_HEADER_END@ 
  25 #include <console/video_console.h> 
  26 #include <kdp/kdp_udp.h> 
  27 #include <kern/debug.h> 
  29 #include "panic_image.c" 
  30 #include "rendered_numbers.c" 
  32 extern struct vc_info vinfo
; 
  33 extern boolean_t panicDialogDesired
; 
  35 /* panic image clut */ 
  36 static const unsigned char *clut 
= NULL
; 
  37 extern void panic_ui_initialize(const unsigned char * system_clut
); 
  39 /* We use this standard MacOS clut as a fallback */ 
  40 static const unsigned char appleClut8
[ 256 * 3 ] = {  
  42         0xFF,0xFF,0xFF, 0xFF,0xFF,0xCC, 0xFF,0xFF,0x99, 0xFF,0xFF,0x66, 
  43         0xFF,0xFF,0x33, 0xFF,0xFF,0x00, 0xFF,0xCC,0xFF, 0xFF,0xCC,0xCC, 
  44         0xFF,0xCC,0x99, 0xFF,0xCC,0x66, 0xFF,0xCC,0x33, 0xFF,0xCC,0x00, 
  45         0xFF,0x99,0xFF, 0xFF,0x99,0xCC, 0xFF,0x99,0x99, 0xFF,0x99,0x66, 
  47         0xFF,0x99,0x33, 0xFF,0x99,0x00, 0xFF,0x66,0xFF, 0xFF,0x66,0xCC, 
  48         0xFF,0x66,0x99, 0xFF,0x66,0x66, 0xFF,0x66,0x33, 0xFF,0x66,0x00, 
  49         0xFF,0x33,0xFF, 0xFF,0x33,0xCC, 0xFF,0x33,0x99, 0xFF,0x33,0x66, 
  50         0xFF,0x33,0x33, 0xFF,0x33,0x00, 0xFF,0x00,0xFF, 0xFF,0x00,0xCC, 
  52         0xFF,0x00,0x99, 0xFF,0x00,0x66, 0xFF,0x00,0x33, 0xFF,0x00,0x00, 
  53         0xCC,0xFF,0xFF, 0xCC,0xFF,0xCC, 0xCC,0xFF,0x99, 0xCC,0xFF,0x66, 
  54         0xCC,0xFF,0x33, 0xCC,0xFF,0x00, 0xCC,0xCC,0xFF, 0xCC,0xCC,0xCC, 
  55         0xCC,0xCC,0x99, 0xCC,0xCC,0x66, 0xCC,0xCC,0x33, 0xCC,0xCC,0x00, 
  57         0xCC,0x99,0xFF, 0xCC,0x99,0xCC, 0xCC,0x99,0x99, 0xCC,0x99,0x66, 
  58         0xCC,0x99,0x33, 0xCC,0x99,0x00, 0xCC,0x66,0xFF, 0xCC,0x66,0xCC, 
  59         0xCC,0x66,0x99, 0xCC,0x66,0x66, 0xCC,0x66,0x33, 0xCC,0x66,0x00, 
  60         0xCC,0x33,0xFF, 0xCC,0x33,0xCC, 0xCC,0x33,0x99, 0xCC,0x33,0x66, 
  62         0xCC,0x33,0x33, 0xCC,0x33,0x00, 0xCC,0x00,0xFF, 0xCC,0x00,0xCC, 
  63         0xCC,0x00,0x99, 0xCC,0x00,0x66, 0xCC,0x00,0x33, 0xCC,0x00,0x00, 
  64         0x99,0xFF,0xFF, 0x99,0xFF,0xCC, 0x99,0xFF,0x99, 0x99,0xFF,0x66, 
  65         0x99,0xFF,0x33, 0x99,0xFF,0x00, 0x99,0xCC,0xFF, 0x99,0xCC,0xCC, 
  67         0x99,0xCC,0x99, 0x99,0xCC,0x66, 0x99,0xCC,0x33, 0x99,0xCC,0x00, 
  68         0x99,0x99,0xFF, 0x99,0x99,0xCC, 0x99,0x99,0x99, 0x99,0x99,0x66, 
  69         0x99,0x99,0x33, 0x99,0x99,0x00, 0x99,0x66,0xFF, 0x99,0x66,0xCC, 
  70         0x99,0x66,0x99, 0x99,0x66,0x66, 0x99,0x66,0x33, 0x99,0x66,0x00, 
  72         0x99,0x33,0xFF, 0x99,0x33,0xCC, 0x99,0x33,0x99, 0x99,0x33,0x66, 
  73         0x99,0x33,0x33, 0x99,0x33,0x00, 0x99,0x00,0xFF, 0x99,0x00,0xCC, 
  74         0x99,0x00,0x99, 0x99,0x00,0x66, 0x99,0x00,0x33, 0x99,0x00,0x00, 
  75         0x66,0xFF,0xFF, 0x66,0xFF,0xCC, 0x66,0xFF,0x99, 0x66,0xFF,0x66, 
  77         0x66,0xFF,0x33, 0x66,0xFF,0x00, 0x66,0xCC,0xFF, 0x66,0xCC,0xCC, 
  78         0x66,0xCC,0x99, 0x66,0xCC,0x66, 0x66,0xCC,0x33, 0x66,0xCC,0x00, 
  79         0x66,0x99,0xFF, 0x66,0x99,0xCC, 0x66,0x99,0x99, 0x66,0x99,0x66, 
  80         0x66,0x99,0x33, 0x66,0x99,0x00, 0x66,0x66,0xFF, 0x66,0x66,0xCC, 
  82         0x66,0x66,0x99, 0x66,0x66,0x66, 0x66,0x66,0x33, 0x66,0x66,0x00, 
  83         0x66,0x33,0xFF, 0x66,0x33,0xCC, 0x66,0x33,0x99, 0x66,0x33,0x66, 
  84         0x66,0x33,0x33, 0x66,0x33,0x00, 0x66,0x00,0xFF, 0x66,0x00,0xCC, 
  85         0x66,0x00,0x99, 0x66,0x00,0x66, 0x66,0x00,0x33, 0x66,0x00,0x00, 
  87         0x33,0xFF,0xFF, 0x33,0xFF,0xCC, 0x33,0xFF,0x99, 0x33,0xFF,0x66, 
  88         0x33,0xFF,0x33, 0x33,0xFF,0x00, 0x33,0xCC,0xFF, 0x33,0xCC,0xCC, 
  89         0x33,0xCC,0x99, 0x33,0xCC,0x66, 0x33,0xCC,0x33, 0x33,0xCC,0x00, 
  90         0x33,0x99,0xFF, 0x33,0x99,0xCC, 0x33,0x99,0x99, 0x33,0x99,0x66, 
  92         0x33,0x99,0x33, 0x33,0x99,0x00, 0x33,0x66,0xFF, 0x33,0x66,0xCC, 
  93         0x33,0x66,0x99, 0x33,0x66,0x66, 0x33,0x66,0x33, 0x33,0x66,0x00, 
  94         0x33,0x33,0xFF, 0x33,0x33,0xCC, 0x33,0x33,0x99, 0x33,0x33,0x66, 
  95         0x33,0x33,0x33, 0x33,0x33,0x00, 0x33,0x00,0xFF, 0x33,0x00,0xCC, 
  97         0x33,0x00,0x99, 0x33,0x00,0x66, 0x33,0x00,0x33, 0x33,0x00,0x00, 
  98         0x00,0xFF,0xFF, 0x00,0xFF,0xCC, 0x00,0xFF,0x99, 0x00,0xFF,0x66, 
  99         0x00,0xFF,0x33, 0x00,0xFF,0x00, 0x00,0xCC,0xFF, 0x00,0xCC,0xCC, 
 100         0x00,0xCC,0x99, 0x00,0xCC,0x66, 0x00,0xCC,0x33, 0x00,0xCC,0x00, 
 102         0x00,0x99,0xFF, 0x00,0x99,0xCC, 0x00,0x99,0x99, 0x00,0x99,0x66, 
 103         0x00,0x99,0x33, 0x00,0x99,0x00, 0x00,0x66,0xFF, 0x00,0x66,0xCC, 
 104         0x00,0x66,0x99, 0x00,0x66,0x66, 0x00,0x66,0x33, 0x00,0x66,0x00, 
 105         0x00,0x33,0xFF, 0x00,0x33,0xCC, 0x00,0x33,0x99, 0x00,0x33,0x66, 
 107         0x00,0x33,0x33, 0x00,0x33,0x00, 0x00,0x00,0xFF, 0x00,0x00,0xCC, 
 108         0x00,0x00,0x99, 0x00,0x00,0x66, 0x00,0x00,0x33, 0xEE,0x00,0x00, 
 109         0xDD,0x00,0x00, 0xBB,0x00,0x00, 0xAA,0x00,0x00, 0x88,0x00,0x00, 
 110         0x77,0x00,0x00, 0x55,0x00,0x00, 0x44,0x00,0x00, 0x22,0x00,0x00, 
 112         0x11,0x00,0x00, 0x00,0xEE,0x00, 0x00,0xDD,0x00, 0x00,0xBB,0x00, 
 113         0x00,0xAA,0x00, 0x00,0x88,0x00, 0x00,0x77,0x00, 0x00,0x55,0x00, 
 114         0x00,0x44,0x00, 0x00,0x22,0x00, 0x00,0x11,0x00, 0x00,0x00,0xEE, 
 115         0x00,0x00,0xDD, 0x00,0x00,0xBB, 0x00,0x00,0xAA, 0x00,0x00,0x88, 
 117         0x00,0x00,0x77, 0x00,0x00,0x55, 0x00,0x00,0x44, 0x00,0x00,0x22, 
 118         0x00,0x00,0x11, 0xEE,0xEE,0xEE, 0xDD,0xDD,0xDD, 0xBB,0xBB,0xBB, 
 119         0xAA,0xAA,0xAA, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55, 
 120         0x44,0x44,0x44, 0x22,0x22,0x22, 0x11,0x11,0x11, 0x00,0x00,0x00 
 124 /* panic dialog and info saving */ 
 125 static int mac_addr_digit_x
; 
 126 static int mac_addr_digit_y
; 
 127 static void blit_digit( int digit 
); 
 128 static boolean_t panicDialogDrawn 
= FALSE
; 
 131 panic_blit_rect(        unsigned int x
, unsigned int y
, 
 132                         unsigned int width
, unsigned int height
, 
 133                         int transparent
, unsigned char * dataPtr 
); 
 136 panic_blit_rect_8(      unsigned int x
, unsigned int y
, 
 137                         unsigned int width
, unsigned int height
, 
 138                         int transparent
, unsigned char * dataPtr 
); 
 141 panic_blit_rect_16(     unsigned int x
, unsigned int y
, 
 142                         unsigned int width
, unsigned int height
, 
 143                         int transparent
, unsigned char * dataPtr 
); 
 146 panic_blit_rect_32(     unsigned int x
, unsigned int y
, 
 147                         unsigned int width
, unsigned int height
, 
 148                         int transparent
, unsigned char * dataPtr 
); 
 160 decode_rle( unsigned char * dataPtr
, unsigned int * quantity
, unsigned int * value 
); 
 163 panic_ui_initialize(const unsigned char * system_clut
) 
 169 draw_panic_dialog( void ) 
 171         int pd_x
,pd_y
, iconx
, icony
, tx_line
, tx_col
; 
 173         int f1
, f2
, d1
, d2
, d3
, rem
; 
 180         struct ether_addr kdp_mac_addr  
= kdp_get_mac_addr(); 
 181         unsigned int ip_addr 
= (unsigned int) ntohl(kdp_get_ip_address()); 
 183         if (!panicDialogDrawn 
&& panicDialogDesired
) 
 185                 if ( !logPanicDataToScreen 
) 
 188                         /* dim the screen 50% before putting up panic dialog */ 
 191                         /* set up to draw background box */ 
 192                         pd_x 
= (vinfo
.v_width
/2) - panic_dialog
.pd_width
/2; 
 193                         pd_y 
= (vinfo
.v_height
/2) - panic_dialog
.pd_height
/2; 
 196                         panic_blit_rect( pd_x
, pd_y
, panic_dialog
.pd_width
, panic_dialog
.pd_height
, 0, (unsigned char*) panic_dialog
.image_pixel_data
); 
 198                         /* do not display the mac and ip addresses if the machine isn't attachable. */ 
 199                         /* there's no sense in possibly confusing people. */ 
 203                                 /* offset for mac address text */ 
 204                                 mac_addr_digit_x 
= (vinfo
.v_width
/2) - 130; /* use 62 if no ip */ 
 205                                 mac_addr_digit_y 
= (vinfo
.v_height
/2) + panic_dialog
.pd_height
/2 - 20; 
 207                                 if(kdp_mac_addr
.ether_addr_octet
[0] || kdp_mac_addr
.ether_addr_octet
[1]|| kdp_mac_addr
.ether_addr_octet
[2] 
 208                                         || kdp_mac_addr
.ether_addr_octet
[3] || kdp_mac_addr
.ether_addr_octet
[4] || kdp_mac_addr
.ether_addr_octet
[5]) 
 210                                         /* blit the digits for mac address */ 
 211                                         for (count 
= 0; count 
< 6; count
++ ) 
 213                                                 nibble 
=  (kdp_mac_addr
.ether_addr_octet
[count
] & 0xf0) >> 4; 
 214                                                 digit 
= nibble 
< 10 ? nibble 
+ '0':nibble 
- 10 + 'a'; 
 217                                                 nibble 
=  kdp_mac_addr
.ether_addr_octet
[count
] & 0xf; 
 218                                                 digit 
= nibble 
< 10 ? nibble 
+ '0':nibble 
- 10 + 'a'; 
 224                                 else    /* blit the ff's */ 
 226                                         for( count 
= 0; count 
< 6; count
++ ) 
 236                                 /* now print the ip address */ 
 237                                 mac_addr_digit_x 
= (vinfo
.v_width
/2) + 10; 
 240                                         /* blit the digits for ip address */ 
 241                                         for (count 
= 0; count 
< 4; count
++ ) 
 243                                                 nibble 
= (ip_addr 
& 0xff000000 ) >> 24; 
 245                                                 d3 
= (nibble 
% 0xa) + '0'; 
 247                                                 d2 
= (nibble 
% 0xa) + '0'; 
 248                                                 nibble 
= nibble 
/0xa; 
 249                                                 d1 
= (nibble 
% 0xa) + '0'; 
 251                                                 if( d1 
!= '0' ) blit_digit(d1
); 
 258                                                 ip_addr 
= ip_addr 
<< 8; 
 264         panicDialogDrawn 
= TRUE
; 
 265         panicDialogDesired 
= FALSE
; 
 270 blit_digit( int digit 
) 
 275                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_0
.num_w
, num_0
.num_h
, 255, (unsigned char*) num_0
.num_pixel_data
); 
 276                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_0
.num_w 
- 1; 
 280                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_1
.num_w
, num_1
.num_h
, 255, (unsigned char*) num_1
.num_pixel_data
); 
 281                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_1
.num_w 
; 
 285                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_2
.num_w
, num_2
.num_h
, 255, (unsigned char*) num_2
.num_pixel_data
); 
 286                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_2
.num_w 
; 
 290                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_3
.num_w
, num_3
.num_h
, 255, (unsigned char*) num_3
.num_pixel_data
); 
 291                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_3
.num_w 
; 
 295                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_4
.num_w
, num_4
.num_h
, 255, (unsigned char*) num_4
.num_pixel_data
); 
 296                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_4
.num_w 
; 
 300                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_5
.num_w
, num_5
.num_h
, 255, (unsigned char*) num_5
.num_pixel_data
); 
 301                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_5
.num_w 
; 
 305                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_6
.num_w
, num_6
.num_h
, 255, (unsigned char*) num_6
.num_pixel_data
); 
 306                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_6
.num_w 
; 
 310                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_7
.num_w
, num_7
.num_h
, 255, (unsigned char*) num_7
.num_pixel_data
); 
 311                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_7
.num_w 
; 
 315                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_8
.num_w
, num_8
.num_h
, 255, (unsigned char*) num_8
.num_pixel_data
); 
 316                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_8
.num_w 
; 
 320                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_9
.num_w
, num_9
.num_h
, 255, (unsigned char*) num_9
.num_pixel_data
); 
 321                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_9
.num_w 
; 
 325                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_a
.num_w
, num_a
.num_h
, 255, (unsigned char*) num_a
.num_pixel_data
); 
 326                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_a
.num_w 
; 
 330                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_b
.num_w
, num_b
.num_h
, 255, (unsigned char*) num_b
.num_pixel_data
); 
 331                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_b
.num_w 
; 
 335                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_c
.num_w
, num_c
.num_h
, 255, (unsigned char*) num_c
.num_pixel_data
); 
 336                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_c
.num_w 
; 
 340                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_d
.num_w
, num_d
.num_h
, 255, (unsigned char*) num_d
.num_pixel_data
); 
 341                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_d
.num_w 
; 
 345                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_e
.num_w
, num_e
.num_h
, 255, (unsigned char*) num_e
.num_pixel_data
); 
 346                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_e
.num_w 
; 
 350                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_f
.num_w
, num_f
.num_h
, 255, (unsigned char*) num_f
.num_pixel_data
); 
 351                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_f
.num_w 
; 
 355                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_colon
.num_w
, num_colon
.num_h
, 255, (unsigned char*) num_colon
.num_pixel_data
); 
 356                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_colon
.num_w
; 
 360                         panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y 
+ (num_colon
.num_h
/2), num_colon
.num_w
, num_colon
.num_h
/2, 255, (unsigned char*) num_colon
.num_pixel_data
); 
 361                         mac_addr_digit_x 
= mac_addr_digit_x 
+ num_colon
.num_w
; 
 371 panic_blit_rect(        unsigned int x
, unsigned int y
, 
 372                         unsigned int width
, unsigned int height
, 
 373                         int transparent
, unsigned char * dataPtr 
) 
 378     switch( vinfo
.v_depth
) { 
 380             panic_blit_rect_8( x
, y
, width
, height
, transparent
, dataPtr
); 
 383             panic_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
); 
 386             panic_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
); 
 391 /*      panic_blit_rect_8 uses the built in clut for drawing. 
 395 panic_blit_rect_8(      unsigned int x
, unsigned int y
, 
 396                         unsigned int width
, unsigned int height
, 
 397                         int transparent
, unsigned char * dataPtr 
) 
 399         volatile unsigned char * dst
; 
 401         unsigned int data
, quantity
, value
; 
 403         dst 
= (volatile unsigned char *) (vinfo
.v_baseaddr 
+ 
 404                                           (y 
* vinfo
.v_rowbytes
) + 
 409         for( line 
= 0; line 
< height
; line
++) { 
 410                 for( col 
= 0; col 
< width
; col
++) { 
 412                                 dataPtr 
+= decode_rle(dataPtr
, &quantity
, &value
); 
 420                 dst 
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
); 
 424 /*      panic_blit_rect_16 draws using a clut. 
 426         panic_blit_rect_16 decodes the RLE encoded image data on the fly, looks up the 
 427         color by indexing into the clut, uses the top 5 bits to fill in each of the three  
 428         pixel values (RGB) and writes each pixel to the screen. 
 431  panic_blit_rect_16(    unsigned int x
, unsigned int y
, 
 432                          unsigned int width
, unsigned int height
, 
 433                          int transparent
, unsigned char * dataPtr 
) 
 435          volatile unsigned short * dst
; 
 437          unsigned int  quantity
, index
, value
, data
; 
 439          /* If our clut has disappeared, use the standard MacOS 8-bit clut */ 
 444          dst 
= (volatile unsigned short *) (vinfo
.v_baseaddr 
+ 
 445                                             (y 
* vinfo
.v_rowbytes
) + 
 450          for( line 
= 0; line 
< height
; line
++) { 
 451                  for( col 
= 0; col 
< width
; col
++) { 
 454                                  dataPtr 
+= decode_rle(dataPtr
, &quantity
, &value
); 
 458                          data 
= ( (unsigned short) (0xf8 & (clut
[index 
+ 0])) << 7) 
 459                                  | ( (unsigned short) (0xf8 & (clut
[index 
+ 1])) << 2) 
 460                                  | ( (unsigned short) (0xf8 & (clut
[index 
+ 2])) >> 3); 
 466                  dst 
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
); 
 472          panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills 
 473          in each of the three pixel values from the clut (RGB) for each pixel and  
 474          writes it to the screen. 
 477  panic_blit_rect_32(    unsigned int x
, unsigned int y
, 
 478                          unsigned int width
, unsigned int height
, 
 479                          int transparent
, unsigned char * dataPtr 
) 
 481          volatile unsigned int * dst
; 
 483          unsigned int value
, quantity
, index
, data
; 
 486         /* If our clut has disappeared, use the standard MacOS 8-bit clut */ 
 491         dst 
= (volatile unsigned int *) (vinfo
.v_baseaddr 
+ 
 492                                          (y 
* vinfo
.v_rowbytes
) + 
 497         for( line 
= 0; line 
< height
; line
++) { 
 498                 for( col 
= 0; col 
< width
; col
++) { 
 500                                 dataPtr 
+= decode_rle(dataPtr
, &quantity
, &value
); 
 504                         data 
= ( (unsigned int) clut
[index 
+ 0] << 16) 
 505                                 | ( (unsigned int) clut
[index 
+ 1] << 8) 
 506                                 | ( (unsigned int) clut
[index 
+ 2]); 
 512                 dst 
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
); 
 517         decode_rle decodes a single quantity/value pair of a "modified-RLE" encoded 
 518         image. The encoding works as follows: 
 520         The quantity and value will be described by either two or three bytes. If the 
 521         most significant bit of the first byte is a 0, then the next seven bits are 
 522         the quantity (run-length) and the following 8 bits are the value (index into 
 523         a clut, in this case). If the msb of the first byte is a 1, then the next 15 bits 
 524         are the quantity and the following 8 are the value. Visually, the two possible 
 525         encodings are: (q = quantity, v = value) 
 528   case 1: [ 0 q6 q5 q4 q3 q2 q1 q0 ]       [ v7 v6 v5 v4 v3 v2 v1 v0 ]  [ ] 
 529   case 2: [ 1 q14 q13 q12 a11 q10 q9 q8 ]  [ q7 q6 q5 q4 q3 q2 q1 q0 ]  [ v7 v6 v5 v4 v3 v2 v1 v0 ] 
 532 decode_rle( unsigned char * dataPtr
, unsigned int * quantity
, unsigned int * value 
) 
 534         unsigned char byte1 
= *dataPtr
++; 
 535         unsigned char byte2 
= *dataPtr
++; 
 538         /* if the most-significant bit is 0, then the first byte is quanity, the second is value */ 
 539         if ((byte1 
>> 7) ==  0) { 
 540                 *quantity 
= (unsigned int) byte1
; 
 541                 *value 
= (unsigned int) byte2
; 
 544                 /* clear the leading 1 */ 
 547                 /* the first two bytes are the quantity, the third is value */ 
 548                 *quantity 
= (unsigned int) byte1 
<< 8 | byte2
; 
 562     switch( vinfo
.v_depth
) { 
 575         unsigned long *p
, *endp
, *row
; 
 577         int      rowline
, rowlongs
; 
 578         unsigned long value
, tmp
; 
 580         rowline 
= vinfo
.v_rowscanbytes 
/ 4; 
 581         rowlongs 
= vinfo
.v_rowbytes 
/ 4; 
 583         p 
= (unsigned long*) vinfo
.v_baseaddr
; 
 584         endp 
= (unsigned long*) vinfo
.v_baseaddr
; 
 586         endp 
+= rowlongs 
* vinfo
.v_height
; 
 588         for (row 
= p 
; row 
< endp 
; row 
+= rowlongs
) { 
 589                 for (col 
= 0; col 
< rowline
; col
++) { 
 591                         tmp 
=  ((value 
& 0x7C007C00) >> 1) & 0x3C003C00; 
 592                         tmp 
|= ((value 
& 0x03E003E0) >> 1) & 0x01E001E0; 
 593                         tmp 
|= ((value 
& 0x001F001F) >> 1) & 0x000F000F; 
 594                         *(row
+col
) = tmp
;               //half (dimmed)? 
 604         unsigned long *p
, *endp
, *row
; 
 606         int      rowline
, rowlongs
; 
 607         unsigned long value
, tmp
; 
 609         rowline 
= vinfo
.v_rowscanbytes 
/ 4; 
 610         rowlongs 
= vinfo
.v_rowbytes 
/ 4; 
 612         p 
= (unsigned long*) vinfo
.v_baseaddr
; 
 613         endp 
= (unsigned long*) vinfo
.v_baseaddr
; 
 615         endp 
+= rowlongs 
* vinfo
.v_height
; 
 617         for (row 
= p 
; row 
< endp 
; row 
+= rowlongs
) { 
 618                 for (col 
= 0; col 
< rowline
; col
++) { 
 620                         tmp 
=  ((value 
& 0x00FF0000) >> 1) & 0x007F0000; 
 621                         tmp 
|= ((value 
& 0x0000FF00) >> 1) & 0x00007F00; 
 622                         tmp 
|= (value 
& 0x000000FF) >> 1; 
 623                         *(row
+col
) = tmp
;               //half (dimmed)?