]> git.saurik.com Git - apple/xnu.git/blame - osfmk/console/panic_dialog.c
xnu-517.tar.gz
[apple/xnu.git] / osfmk / console / panic_dialog.c
CommitLineData
55e303ae
A
1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26#include <vc.h>
27
28#include <console/video_console.h>
29#include <kdp/kdp_udp.h>
30#include <kern/debug.h>
31
32#include "panic_image.c"
33#include "rendered_numbers.c"
34
35extern struct vc_info vinfo;
36extern boolean_t panicDialogDesired;
37
38/* panic image clut */
39static const unsigned char *clut = NULL;
40extern void panic_ui_initialize(const unsigned char * system_clut);
41
42/* We use this standard MacOS clut as a fallback */
43static const unsigned char appleClut8[ 256 * 3 ] = {
44// 00
45 0xFF,0xFF,0xFF, 0xFF,0xFF,0xCC, 0xFF,0xFF,0x99, 0xFF,0xFF,0x66,
46 0xFF,0xFF,0x33, 0xFF,0xFF,0x00, 0xFF,0xCC,0xFF, 0xFF,0xCC,0xCC,
47 0xFF,0xCC,0x99, 0xFF,0xCC,0x66, 0xFF,0xCC,0x33, 0xFF,0xCC,0x00,
48 0xFF,0x99,0xFF, 0xFF,0x99,0xCC, 0xFF,0x99,0x99, 0xFF,0x99,0x66,
49// 10
50 0xFF,0x99,0x33, 0xFF,0x99,0x00, 0xFF,0x66,0xFF, 0xFF,0x66,0xCC,
51 0xFF,0x66,0x99, 0xFF,0x66,0x66, 0xFF,0x66,0x33, 0xFF,0x66,0x00,
52 0xFF,0x33,0xFF, 0xFF,0x33,0xCC, 0xFF,0x33,0x99, 0xFF,0x33,0x66,
53 0xFF,0x33,0x33, 0xFF,0x33,0x00, 0xFF,0x00,0xFF, 0xFF,0x00,0xCC,
54// 20
55 0xFF,0x00,0x99, 0xFF,0x00,0x66, 0xFF,0x00,0x33, 0xFF,0x00,0x00,
56 0xCC,0xFF,0xFF, 0xCC,0xFF,0xCC, 0xCC,0xFF,0x99, 0xCC,0xFF,0x66,
57 0xCC,0xFF,0x33, 0xCC,0xFF,0x00, 0xCC,0xCC,0xFF, 0xCC,0xCC,0xCC,
58 0xCC,0xCC,0x99, 0xCC,0xCC,0x66, 0xCC,0xCC,0x33, 0xCC,0xCC,0x00,
59// 30
60 0xCC,0x99,0xFF, 0xCC,0x99,0xCC, 0xCC,0x99,0x99, 0xCC,0x99,0x66,
61 0xCC,0x99,0x33, 0xCC,0x99,0x00, 0xCC,0x66,0xFF, 0xCC,0x66,0xCC,
62 0xCC,0x66,0x99, 0xCC,0x66,0x66, 0xCC,0x66,0x33, 0xCC,0x66,0x00,
63 0xCC,0x33,0xFF, 0xCC,0x33,0xCC, 0xCC,0x33,0x99, 0xCC,0x33,0x66,
64// 40
65 0xCC,0x33,0x33, 0xCC,0x33,0x00, 0xCC,0x00,0xFF, 0xCC,0x00,0xCC,
66 0xCC,0x00,0x99, 0xCC,0x00,0x66, 0xCC,0x00,0x33, 0xCC,0x00,0x00,
67 0x99,0xFF,0xFF, 0x99,0xFF,0xCC, 0x99,0xFF,0x99, 0x99,0xFF,0x66,
68 0x99,0xFF,0x33, 0x99,0xFF,0x00, 0x99,0xCC,0xFF, 0x99,0xCC,0xCC,
69// 50
70 0x99,0xCC,0x99, 0x99,0xCC,0x66, 0x99,0xCC,0x33, 0x99,0xCC,0x00,
71 0x99,0x99,0xFF, 0x99,0x99,0xCC, 0x99,0x99,0x99, 0x99,0x99,0x66,
72 0x99,0x99,0x33, 0x99,0x99,0x00, 0x99,0x66,0xFF, 0x99,0x66,0xCC,
73 0x99,0x66,0x99, 0x99,0x66,0x66, 0x99,0x66,0x33, 0x99,0x66,0x00,
74// 60
75 0x99,0x33,0xFF, 0x99,0x33,0xCC, 0x99,0x33,0x99, 0x99,0x33,0x66,
76 0x99,0x33,0x33, 0x99,0x33,0x00, 0x99,0x00,0xFF, 0x99,0x00,0xCC,
77 0x99,0x00,0x99, 0x99,0x00,0x66, 0x99,0x00,0x33, 0x99,0x00,0x00,
78 0x66,0xFF,0xFF, 0x66,0xFF,0xCC, 0x66,0xFF,0x99, 0x66,0xFF,0x66,
79// 70
80 0x66,0xFF,0x33, 0x66,0xFF,0x00, 0x66,0xCC,0xFF, 0x66,0xCC,0xCC,
81 0x66,0xCC,0x99, 0x66,0xCC,0x66, 0x66,0xCC,0x33, 0x66,0xCC,0x00,
82 0x66,0x99,0xFF, 0x66,0x99,0xCC, 0x66,0x99,0x99, 0x66,0x99,0x66,
83 0x66,0x99,0x33, 0x66,0x99,0x00, 0x66,0x66,0xFF, 0x66,0x66,0xCC,
84// 80
85 0x66,0x66,0x99, 0x66,0x66,0x66, 0x66,0x66,0x33, 0x66,0x66,0x00,
86 0x66,0x33,0xFF, 0x66,0x33,0xCC, 0x66,0x33,0x99, 0x66,0x33,0x66,
87 0x66,0x33,0x33, 0x66,0x33,0x00, 0x66,0x00,0xFF, 0x66,0x00,0xCC,
88 0x66,0x00,0x99, 0x66,0x00,0x66, 0x66,0x00,0x33, 0x66,0x00,0x00,
89// 90
90 0x33,0xFF,0xFF, 0x33,0xFF,0xCC, 0x33,0xFF,0x99, 0x33,0xFF,0x66,
91 0x33,0xFF,0x33, 0x33,0xFF,0x00, 0x33,0xCC,0xFF, 0x33,0xCC,0xCC,
92 0x33,0xCC,0x99, 0x33,0xCC,0x66, 0x33,0xCC,0x33, 0x33,0xCC,0x00,
93 0x33,0x99,0xFF, 0x33,0x99,0xCC, 0x33,0x99,0x99, 0x33,0x99,0x66,
94// a0
95 0x33,0x99,0x33, 0x33,0x99,0x00, 0x33,0x66,0xFF, 0x33,0x66,0xCC,
96 0x33,0x66,0x99, 0x33,0x66,0x66, 0x33,0x66,0x33, 0x33,0x66,0x00,
97 0x33,0x33,0xFF, 0x33,0x33,0xCC, 0x33,0x33,0x99, 0x33,0x33,0x66,
98 0x33,0x33,0x33, 0x33,0x33,0x00, 0x33,0x00,0xFF, 0x33,0x00,0xCC,
99// b0
100 0x33,0x00,0x99, 0x33,0x00,0x66, 0x33,0x00,0x33, 0x33,0x00,0x00,
101 0x00,0xFF,0xFF, 0x00,0xFF,0xCC, 0x00,0xFF,0x99, 0x00,0xFF,0x66,
102 0x00,0xFF,0x33, 0x00,0xFF,0x00, 0x00,0xCC,0xFF, 0x00,0xCC,0xCC,
103 0x00,0xCC,0x99, 0x00,0xCC,0x66, 0x00,0xCC,0x33, 0x00,0xCC,0x00,
104// c0
105 0x00,0x99,0xFF, 0x00,0x99,0xCC, 0x00,0x99,0x99, 0x00,0x99,0x66,
106 0x00,0x99,0x33, 0x00,0x99,0x00, 0x00,0x66,0xFF, 0x00,0x66,0xCC,
107 0x00,0x66,0x99, 0x00,0x66,0x66, 0x00,0x66,0x33, 0x00,0x66,0x00,
108 0x00,0x33,0xFF, 0x00,0x33,0xCC, 0x00,0x33,0x99, 0x00,0x33,0x66,
109// d0
110 0x00,0x33,0x33, 0x00,0x33,0x00, 0x00,0x00,0xFF, 0x00,0x00,0xCC,
111 0x00,0x00,0x99, 0x00,0x00,0x66, 0x00,0x00,0x33, 0xEE,0x00,0x00,
112 0xDD,0x00,0x00, 0xBB,0x00,0x00, 0xAA,0x00,0x00, 0x88,0x00,0x00,
113 0x77,0x00,0x00, 0x55,0x00,0x00, 0x44,0x00,0x00, 0x22,0x00,0x00,
114// e0
115 0x11,0x00,0x00, 0x00,0xEE,0x00, 0x00,0xDD,0x00, 0x00,0xBB,0x00,
116 0x00,0xAA,0x00, 0x00,0x88,0x00, 0x00,0x77,0x00, 0x00,0x55,0x00,
117 0x00,0x44,0x00, 0x00,0x22,0x00, 0x00,0x11,0x00, 0x00,0x00,0xEE,
118 0x00,0x00,0xDD, 0x00,0x00,0xBB, 0x00,0x00,0xAA, 0x00,0x00,0x88,
119// f0
120 0x00,0x00,0x77, 0x00,0x00,0x55, 0x00,0x00,0x44, 0x00,0x00,0x22,
121 0x00,0x00,0x11, 0xEE,0xEE,0xEE, 0xDD,0xDD,0xDD, 0xBB,0xBB,0xBB,
122 0xAA,0xAA,0xAA, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55,
123 0x44,0x44,0x44, 0x22,0x22,0x22, 0x11,0x11,0x11, 0x00,0x00,0x00
124};
125
126
127/* panic dialog and info saving */
128static int mac_addr_digit_x;
129static int mac_addr_digit_y;
130static void blit_digit( int digit );
131static boolean_t panicDialogDrawn = FALSE;
132
133static void
134panic_blit_rect( unsigned int x, unsigned int y,
135 unsigned int width, unsigned int height,
136 int transparent, unsigned char * dataPtr );
137
138static void
139panic_blit_rect_8( unsigned int x, unsigned int y,
140 unsigned int width, unsigned int height,
141 int transparent, unsigned char * dataPtr );
142
143static void
144panic_blit_rect_16( unsigned int x, unsigned int y,
145 unsigned int width, unsigned int height,
146 int transparent, unsigned char * dataPtr );
147
148static void
149panic_blit_rect_32( unsigned int x, unsigned int y,
150 unsigned int width, unsigned int height,
151 int transparent, unsigned char * dataPtr );
152
153static void
154dim_screen(void);
155
156static void
157dim_screen_16(void);
158
159static void
160dim_screen_32(void);
161
162static int
163decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * value );
164
165void
166panic_ui_initialize(const unsigned char * system_clut)
167{
168 clut = system_clut;
169}
170
171void
172draw_panic_dialog( void )
173{
174 int pd_x,pd_y, iconx, icony, tx_line, tx_col;
175 int line_width = 1;
176 int f1, f2, d1, d2, d3, rem;
177 char *pair = "ff";
178 int count = 0;
179 char digit;
180 int nibble;
181 char colon = ':';
182 char dot = '.';
183 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
184 unsigned int ip_addr = (unsigned int) ntohl(kdp_get_ip_address());
185
186 if (!panicDialogDrawn && panicDialogDesired)
187 {
188 if ( !logPanicDataToScreen )
189 {
190
191 /* dim the screen 50% before putting up panic dialog */
192 dim_screen();
193
194 /* set up to draw background box */
195 pd_x = (vinfo.v_width/2) - panic_dialog.pd_width/2;
196 pd_y = (vinfo.v_height/2) - panic_dialog.pd_height/2;
197
198 /* draw image */
199 panic_blit_rect( pd_x, pd_y, panic_dialog.pd_width, panic_dialog.pd_height, 0, (unsigned char*) panic_dialog.image_pixel_data);
200
201 /* do not display the mac and ip addresses if the machine isn't attachable. */
202 /* there's no sense in possibly confusing people. */
203 if (panicDebugging)
204 {
205
206 /* offset for mac address text */
207 mac_addr_digit_x = (vinfo.v_width/2) - 130; /* use 62 if no ip */
208 mac_addr_digit_y = (vinfo.v_height/2) + panic_dialog.pd_height/2 - 20;
209
210 if(kdp_mac_addr.ether_addr_octet[0] || kdp_mac_addr.ether_addr_octet[1]|| kdp_mac_addr.ether_addr_octet[2]
211 || kdp_mac_addr.ether_addr_octet[3] || kdp_mac_addr.ether_addr_octet[4] || kdp_mac_addr.ether_addr_octet[5])
212 {
213 /* blit the digits for mac address */
214 for (count = 0; count < 6; count++ )
215 {
216 nibble = (kdp_mac_addr.ether_addr_octet[count] & 0xf0) >> 4;
217 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
218 blit_digit(digit);
219
220 nibble = kdp_mac_addr.ether_addr_octet[count] & 0xf;
221 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
222 blit_digit(digit);
223 if( count < 5 )
224 blit_digit( colon );
225 }
226 }
227 else /* blit the ff's */
228 {
229 for( count = 0; count < 6; count++ )
230 {
231 digit = pair[0];
232 blit_digit(digit);
233 digit = pair[1];
234 blit_digit(digit);
235 if( count < 5 )
236 blit_digit( colon );
237 }
238 }
239 /* now print the ip address */
240 mac_addr_digit_x = (vinfo.v_width/2) + 10;
241 if(ip_addr != 0)
242 {
243 /* blit the digits for ip address */
244 for (count = 0; count < 4; count++ )
245 {
246 nibble = (ip_addr & 0xff000000 ) >> 24;
247
248 d3 = (nibble % 0xa) + '0';
249 nibble = nibble/0xa;
250 d2 = (nibble % 0xa) + '0';
251 nibble = nibble /0xa;
252 d1 = (nibble % 0xa) + '0';
253
254 if( d1 != '0' ) blit_digit(d1);
255 blit_digit(d2);
256 blit_digit(d3);
257 if( count < 3 )
258 blit_digit(dot);
259
260 d1= d2 = d3 = 0;
261 ip_addr = ip_addr << 8;
262 }
263 }
264 }
265 }
266 }
267 panicDialogDrawn = TRUE;
268 panicDialogDesired = FALSE;
269
270}
271
272static void
273blit_digit( int digit )
274{
275 switch( digit )
276 {
277 case '0': {
278 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);
279 mac_addr_digit_x = mac_addr_digit_x + num_0.num_w - 1;
280 break;
281 }
282 case '1': {
283 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);
284 mac_addr_digit_x = mac_addr_digit_x + num_1.num_w ;
285 break;
286 }
287 case '2': {
288 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);
289 mac_addr_digit_x = mac_addr_digit_x + num_2.num_w ;
290 break;
291 }
292 case '3': {
293 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);
294 mac_addr_digit_x = mac_addr_digit_x + num_3.num_w ;
295 break;
296 }
297 case '4': {
298 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);
299 mac_addr_digit_x = mac_addr_digit_x + num_4.num_w ;
300 break;
301 }
302 case '5': {
303 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);
304 mac_addr_digit_x = mac_addr_digit_x + num_5.num_w ;
305 break;
306 }
307 case '6': {
308 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);
309 mac_addr_digit_x = mac_addr_digit_x + num_6.num_w ;
310 break;
311 }
312 case '7': {
313 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);
314 mac_addr_digit_x = mac_addr_digit_x + num_7.num_w ;
315 break;
316 }
317 case '8': {
318 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);
319 mac_addr_digit_x = mac_addr_digit_x + num_8.num_w ;
320 break;
321 }
322 case '9': {
323 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);
324 mac_addr_digit_x = mac_addr_digit_x + num_9.num_w ;
325 break;
326 }
327 case 'a': {
328 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);
329 mac_addr_digit_x = mac_addr_digit_x + num_a.num_w ;
330 break;
331 }
332 case 'b': {
333 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);
334 mac_addr_digit_x = mac_addr_digit_x + num_b.num_w ;
335 break;
336 }
337 case 'c': {
338 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);
339 mac_addr_digit_x = mac_addr_digit_x + num_c.num_w ;
340 break;
341 }
342 case 'd': {
343 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);
344 mac_addr_digit_x = mac_addr_digit_x + num_d.num_w ;
345 break;
346 }
347 case 'e': {
348 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);
349 mac_addr_digit_x = mac_addr_digit_x + num_e.num_w ;
350 break;
351 }
352 case 'f': {
353 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);
354 mac_addr_digit_x = mac_addr_digit_x + num_f.num_w ;
355 break;
356 }
357 case ':': {
358 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);
359 mac_addr_digit_x = mac_addr_digit_x + num_colon.num_w;
360 break;
361 }
362 case '.': {
363 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);
364 mac_addr_digit_x = mac_addr_digit_x + num_colon.num_w;
365 break;
366 }
367 default:
368 break;
369
370 }
371}
372
373static void
374panic_blit_rect( unsigned int x, unsigned int y,
375 unsigned int width, unsigned int height,
376 int transparent, unsigned char * dataPtr )
377{
378 if(!vinfo.v_depth)
379 return;
380
381 switch( vinfo.v_depth) {
382 case 8:
383 panic_blit_rect_8( x, y, width, height, transparent, dataPtr);
384 break;
385 case 16:
386 panic_blit_rect_16( x, y, width, height, transparent, dataPtr);
387 break;
388 case 32:
389 panic_blit_rect_32( x, y, width, height, transparent, dataPtr);
390 break;
391 }
392}
393
394/* panic_blit_rect_8 uses the built in clut for drawing.
395
396*/
397static void
398panic_blit_rect_8( unsigned int x, unsigned int y,
399 unsigned int width, unsigned int height,
400 int transparent, unsigned char * dataPtr )
401{
402 volatile unsigned char * dst;
403 int line, col;
404 unsigned int data, quantity, value;
405
406 dst = (volatile unsigned char *) (vinfo.v_baseaddr +
407 (y * vinfo.v_rowbytes) +
408 x);
409
410 quantity = 0;
411
412 for( line = 0; line < height; line++) {
413 for( col = 0; col < width; col++) {
414 if (quantity == 0) {
415 dataPtr += decode_rle(dataPtr, &quantity, &value);
416 }
417
418 data = value;
419 *(dst + col) = data;
420 quantity--;
421 }
422
423 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
424 }
425}
426
427/* panic_blit_rect_16 draws using a clut.
428
429 panic_blit_rect_16 decodes the RLE encoded image data on the fly, looks up the
430 color by indexing into the clut, uses the top 5 bits to fill in each of the three
431 pixel values (RGB) and writes each pixel to the screen.
432*/
433 static void
434 panic_blit_rect_16( unsigned int x, unsigned int y,
435 unsigned int width, unsigned int height,
436 int transparent, unsigned char * dataPtr )
437 {
438 volatile unsigned short * dst;
439 int line, col;
440 unsigned int quantity, index, value, data;
441
442 /* If our clut has disappeared, use the standard MacOS 8-bit clut */
443 if(!clut) {
444 clut = appleClut8;
445 }
446
447 dst = (volatile unsigned short *) (vinfo.v_baseaddr +
448 (y * vinfo.v_rowbytes) +
449 (x * 2));
450
451 quantity = 0;
452
453 for( line = 0; line < height; line++) {
454 for( col = 0; col < width; col++) {
455
456 if (quantity == 0) {
457 dataPtr += decode_rle(dataPtr, &quantity, &value);
458 index = value * 3;
459 }
460
461 data = ( (unsigned short) (0xf8 & (clut[index + 0])) << 7)
462 | ( (unsigned short) (0xf8 & (clut[index + 1])) << 2)
463 | ( (unsigned short) (0xf8 & (clut[index + 2])) >> 3);
464
465 *(dst + col) = data;
466 quantity--;
467 }
468
469 dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
470 }
471
472 }
473
474 /*
475 panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills
476 in each of the three pixel values from the clut (RGB) for each pixel and
477 writes it to the screen.
478 */
479 static void
480 panic_blit_rect_32( unsigned int x, unsigned int y,
481 unsigned int width, unsigned int height,
482 int transparent, unsigned char * dataPtr )
483 {
484 volatile unsigned int * dst;
485 int line, col;
486 unsigned int value, quantity, index, data;
487
488
489 /* If our clut has disappeared, use the standard MacOS 8-bit clut */
490 if(!clut) {
491 clut = appleClut8;
492 }
493
494 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
495 (y * vinfo.v_rowbytes) +
496 (x * 4));
497
498 quantity = 0;
499
500 for( line = 0; line < height; line++) {
501 for( col = 0; col < width; col++) {
502 if (quantity == 0) {
503 dataPtr += decode_rle(dataPtr, &quantity, &value);
504 index = value * 3;
505 }
506
507 data = ( (unsigned int) clut[index + 0] << 16)
508 | ( (unsigned int) clut[index + 1] << 8)
509 | ( (unsigned int) clut[index + 2]);
510
511 *(dst + col) = data;
512 quantity--;
513 }
514
515 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
516 }
517}
518
519/*
520 decode_rle decodes a single quantity/value pair of a "modified-RLE" encoded
521 image. The encoding works as follows:
522
523 The quantity and value will be described by either two or three bytes. If the
524 most significant bit of the first byte is a 0, then the next seven bits are
525 the quantity (run-length) and the following 8 bits are the value (index into
526 a clut, in this case). If the msb of the first byte is a 1, then the next 15 bits
527 are the quantity and the following 8 are the value. Visually, the two possible
528 encodings are: (q = quantity, v = value)
529
530 Byte 1 Byte 2 Byte 3
531 case 1: [ 0 q6 q5 q4 q3 q2 q1 q0 ] [ v7 v6 v5 v4 v3 v2 v1 v0 ] [ ]
532 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 ]
533*/
534static int
535decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * value )
536{
537 unsigned char byte1 = *dataPtr++;
538 unsigned char byte2 = *dataPtr++;
539 int num_slots = 0;
540
541 /* if the most-significant bit is 0, then the first byte is quanity, the second is value */
542 if ((byte1 >> 7) == 0) {
543 *quantity = (unsigned int) byte1;
544 *value = (unsigned int) byte2;
545 num_slots = 2;
546 } else {
547 /* clear the leading 1 */
548 byte1 ^= 0x80;
549
550 /* the first two bytes are the quantity, the third is value */
551 *quantity = (unsigned int) byte1 << 8 | byte2;
552 *value = *dataPtr++;
553 num_slots = 3;
554 }
555
556 return num_slots;
557}
558
559static void
560dim_screen(void)
561{
562 if(!vinfo.v_depth)
563 return;
564
565 switch( vinfo.v_depth) {
566 case 16:
567 dim_screen_16();
568 break;
569 case 32:
570 dim_screen_32();
571 break;
572 }
573}
574
575static void
576dim_screen_16(void)
577{
578 unsigned long *p, *endp, *row;
579 int col;
580 int rowline, rowlongs;
581 unsigned long value, tmp;
582
583 rowline = vinfo.v_rowscanbytes / 4;
584 rowlongs = vinfo.v_rowbytes / 4;
585
586 p = (unsigned long*) vinfo.v_baseaddr;
587 endp = (unsigned long*) vinfo.v_baseaddr;
588
589 endp += rowlongs * vinfo.v_height;
590
591 for (row = p ; row < endp ; row += rowlongs) {
592 for (col = 0; col < rowline; col++) {
593 value = *(row+col);
594 tmp = ((value & 0x7C007C00) >> 1) & 0x3C003C00;
595 tmp |= ((value & 0x03E003E0) >> 1) & 0x01E001E0;
596 tmp |= ((value & 0x001F001F) >> 1) & 0x000F000F;
597 *(row+col) = tmp; //half (dimmed)?
598 }
599
600 }
601
602}
603
604static void
605dim_screen_32(void)
606{
607 unsigned long *p, *endp, *row;
608 int col;
609 int rowline, rowlongs;
610 unsigned long value, tmp;
611
612 rowline = vinfo.v_rowscanbytes / 4;
613 rowlongs = vinfo.v_rowbytes / 4;
614
615 p = (unsigned long*) vinfo.v_baseaddr;
616 endp = (unsigned long*) vinfo.v_baseaddr;
617
618 endp += rowlongs * vinfo.v_height;
619
620 for (row = p ; row < endp ; row += rowlongs) {
621 for (col = 0; col < rowline; col++) {
622 value = *(row+col);
623 tmp = ((value & 0x00FF0000) >> 1) & 0x007F0000;
624 tmp |= ((value & 0x0000FF00) >> 1) & 0x00007F00;
625 tmp |= (value & 0x000000FF) >> 1;
626 *(row+col) = tmp; //half (dimmed)?
627 }
628
629 }
630
631}