]>
Commit | Line | Data |
---|---|---|
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 | ||
35 | extern struct vc_info vinfo; | |
36 | extern boolean_t panicDialogDesired; | |
37 | ||
38 | /* panic image clut */ | |
39 | static const unsigned char *clut = NULL; | |
40 | extern void panic_ui_initialize(const unsigned char * system_clut); | |
41 | ||
42 | /* We use this standard MacOS clut as a fallback */ | |
43 | static 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 */ | |
128 | static int mac_addr_digit_x; | |
129 | static int mac_addr_digit_y; | |
130 | static void blit_digit( int digit ); | |
131 | static boolean_t panicDialogDrawn = FALSE; | |
132 | ||
133 | static void | |
134 | panic_blit_rect( unsigned int x, unsigned int y, | |
135 | unsigned int width, unsigned int height, | |
136 | int transparent, unsigned char * dataPtr ); | |
137 | ||
138 | static void | |
139 | panic_blit_rect_8( unsigned int x, unsigned int y, | |
140 | unsigned int width, unsigned int height, | |
141 | int transparent, unsigned char * dataPtr ); | |
142 | ||
143 | static void | |
144 | panic_blit_rect_16( unsigned int x, unsigned int y, | |
145 | unsigned int width, unsigned int height, | |
146 | int transparent, unsigned char * dataPtr ); | |
147 | ||
148 | static void | |
149 | panic_blit_rect_32( unsigned int x, unsigned int y, | |
150 | unsigned int width, unsigned int height, | |
151 | int transparent, unsigned char * dataPtr ); | |
152 | ||
153 | static void | |
154 | dim_screen(void); | |
155 | ||
156 | static void | |
157 | dim_screen_16(void); | |
158 | ||
159 | static void | |
160 | dim_screen_32(void); | |
161 | ||
162 | static int | |
163 | decode_rle( unsigned char * dataPtr, unsigned int * quantity, unsigned int * value ); | |
164 | ||
165 | void | |
166 | panic_ui_initialize(const unsigned char * system_clut) | |
167 | { | |
168 | clut = system_clut; | |
169 | } | |
170 | ||
171 | void | |
172 | draw_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 | ||
272 | static void | |
273 | blit_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 | ||
373 | static void | |
374 | panic_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 | */ | |
397 | static void | |
398 | panic_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 | */ | |
534 | static int | |
535 | decode_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 | ||
559 | static void | |
560 | dim_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 | ||
575 | static void | |
576 | dim_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 | ||
604 | static void | |
605 | dim_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 | } |