Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Procedures for drawing on the screen early on in the boot process.
  4 *
  5 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
  6 */
  7#include <linux/kernel.h>
  8#include <linux/string.h>
  9#include <linux/init.h>
 10#include <linux/export.h>
 11#include <linux/font.h>
 12#include <linux/memblock.h>
 13#include <linux/pgtable.h>
 14#include <linux/of.h>
 15
 16#include <asm/sections.h>
 
 17#include <asm/btext.h>
 18#include <asm/page.h>
 19#include <asm/mmu.h>
 20#include <asm/io.h>
 21#include <asm/processor.h>
 22#include <asm/udbg.h>
 23
 24#define NO_SCROLL
 25
 26#ifndef NO_SCROLL
 27static void scrollscreen(void);
 28#endif
 29
 30#define __force_data __section(".data")
 31
 32static int g_loc_X __force_data;
 33static int g_loc_Y __force_data;
 34static int g_max_loc_X __force_data;
 35static int g_max_loc_Y __force_data;
 36
 37static int dispDeviceRowBytes __force_data;
 38static int dispDeviceDepth  __force_data;
 39static int dispDeviceRect[4] __force_data;
 40static unsigned char *dispDeviceBase __force_data;
 41static unsigned char *logicalDisplayBase __force_data;
 42
 43unsigned long disp_BAT[2] __initdata = {0, 0};
 44
 45static int boot_text_mapped __force_data;
 
 
 
 
 
 46
 47extern void rmci_on(void);
 48extern void rmci_off(void);
 49
 50static inline void rmci_maybe_on(void)
 51{
 52#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 53	if (!(mfmsr() & MSR_DR))
 54		rmci_on();
 55#endif
 56}
 57
 58static inline void rmci_maybe_off(void)
 59{
 60#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 61	if (!(mfmsr() & MSR_DR))
 62		rmci_off();
 63#endif
 64}
 65
 66
 67#ifdef CONFIG_PPC32
 68/* Calc BAT values for mapping the display and store them
 69 * in disp_BAT.  Those values are then used from head.S to map
 70 * the display during identify_machine() and MMU_Init()
 71 *
 72 * The display is mapped to virtual address 0xD0000000, rather
 73 * than 1:1, because some CHRP machines put the frame buffer
 74 * in the region starting at 0xC0000000 (PAGE_OFFSET).
 75 * This mapping is temporary and will disappear as soon as the
 76 * setup done by MMU_Init() is applied.
 77 *
 78 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
 79 * on other PPCs. This may cause trouble if the framebuffer
 80 * is really badly aligned, but I didn't encounter this case
 81 * yet.
 82 */
 83void __init btext_prepare_BAT(void)
 84{
 85	unsigned long vaddr = PAGE_OFFSET + 0x10000000;
 86	unsigned long addr;
 87	unsigned long lowbits;
 88
 89	addr = (unsigned long)dispDeviceBase;
 90	if (!addr) {
 91		boot_text_mapped = 0;
 92		return;
 93	}
 94	lowbits = addr & ~0xFF000000UL;
 95	addr &= 0xFF000000UL;
 96	disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
 97	disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
 98	logicalDisplayBase = (void *) (vaddr + lowbits);
 99}
100#endif
101
102
103/* This function can be used to enable the early boot text when doing
104 * OF booting or within bootx init. It must be followed by a btext_unmap()
105 * call before the logical address becomes unusable
106 */
107void __init btext_setup_display(int width, int height, int depth, int pitch,
108				unsigned long address)
109{
110	g_loc_X = 0;
111	g_loc_Y = 0;
112	g_max_loc_X = width / 8;
113	g_max_loc_Y = height / 16;
114	logicalDisplayBase = (unsigned char *)address;
115	dispDeviceBase = (unsigned char *)address;
116	dispDeviceRowBytes = pitch;
117	dispDeviceDepth = depth == 15 ? 16 : depth;
118	dispDeviceRect[0] = dispDeviceRect[1] = 0;
119	dispDeviceRect[2] = width;
120	dispDeviceRect[3] = height;
121	boot_text_mapped = 1;
122}
123
124void __init btext_unmap(void)
125{
126	boot_text_mapped = 0;
127}
128
129/* Here's a small text engine to use during early boot
130 * or for debugging purposes
131 *
132 * todo:
133 *
134 *  - build some kind of vgacon with it to enable early printk
135 *  - move to a separate file
136 *  - add a few video driver hooks to keep in sync with display
137 *    changes.
138 */
139
140void btext_map(void)
141{
142	unsigned long base, offset, size;
143	unsigned char *vbase;
144
145	/* By default, we are no longer mapped */
146	boot_text_mapped = 0;
147	if (!dispDeviceBase)
148		return;
149	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
150	offset = ((unsigned long) dispDeviceBase) - base;
151	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
152		+ dispDeviceRect[0];
153	vbase = ioremap_wc(base, size);
154	if (!vbase)
155		return;
156	logicalDisplayBase = vbase + offset;
157	boot_text_mapped = 1;
158}
159
160static int __init btext_initialize(struct device_node *np)
161{
162	unsigned int width, height, depth, pitch;
163	unsigned long address = 0;
164	const u32 *prop;
165
166	prop = of_get_property(np, "linux,bootx-width", NULL);
167	if (prop == NULL)
168		prop = of_get_property(np, "width", NULL);
169	if (prop == NULL)
170		return -EINVAL;
171	width = *prop;
172	prop = of_get_property(np, "linux,bootx-height", NULL);
173	if (prop == NULL)
174		prop = of_get_property(np, "height", NULL);
175	if (prop == NULL)
176		return -EINVAL;
177	height = *prop;
178	prop = of_get_property(np, "linux,bootx-depth", NULL);
179	if (prop == NULL)
180		prop = of_get_property(np, "depth", NULL);
181	if (prop == NULL)
182		return -EINVAL;
183	depth = *prop;
184	pitch = width * ((depth + 7) / 8);
185	prop = of_get_property(np, "linux,bootx-linebytes", NULL);
186	if (prop == NULL)
187		prop = of_get_property(np, "linebytes", NULL);
188	if (prop && *prop != 0xffffffffu)
189		pitch = *prop;
190	if (pitch == 1)
191		pitch = 0x1000;
192	prop = of_get_property(np, "linux,bootx-addr", NULL);
193	if (prop == NULL)
194		prop = of_get_property(np, "address", NULL);
195	if (prop)
196		address = *prop;
197
198	/* FIXME: Add support for PCI reg properties. Right now, only
199	 * reliable on macs
200	 */
201	if (address == 0)
202		return -EINVAL;
203
204	g_loc_X = 0;
205	g_loc_Y = 0;
206	g_max_loc_X = width / 8;
207	g_max_loc_Y = height / 16;
208	dispDeviceBase = (unsigned char *)address;
209	dispDeviceRowBytes = pitch;
210	dispDeviceDepth = depth == 15 ? 16 : depth;
211	dispDeviceRect[0] = dispDeviceRect[1] = 0;
212	dispDeviceRect[2] = width;
213	dispDeviceRect[3] = height;
214
215	btext_map();
216
217	return 0;
218}
219
220int __init btext_find_display(int allow_nonstdout)
221{
222	struct device_node *np = of_stdout;
223	int rc = -ENODEV;
224
225	if (!of_node_is_type(np, "display")) {
226		printk("boot stdout isn't a display !\n");
227		np = NULL;
228	}
229	if (np)
230		rc = btext_initialize(np);
231	if (rc == 0 || !allow_nonstdout)
232		return rc;
233
234	for_each_node_by_type(np, "display") {
235		if (of_property_read_bool(np, "linux,opened")) {
236			printk("trying %pOF ...\n", np);
237			rc = btext_initialize(np);
238			printk("result: %d\n", rc);
239		}
240		if (rc == 0) {
241			of_node_put(np);
242			break;
243		}
244	}
245	return rc;
246}
247
248/* Calc the base address of a given point (x,y) */
249static unsigned char * calc_base(int x, int y)
250{
251	unsigned char *base;
252
253	base = logicalDisplayBase;
254	if (!base)
255		base = dispDeviceBase;
256	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
257	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
258	return base;
259}
260
261/* Adjust the display to a new resolution */
262void btext_update_display(unsigned long phys, int width, int height,
263			  int depth, int pitch)
264{
265	if (!dispDeviceBase)
266		return;
267
268	/* check it's the same frame buffer (within 256MB) */
269	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
270		return;
271
272	dispDeviceBase = (__u8 *) phys;
273	dispDeviceRect[0] = 0;
274	dispDeviceRect[1] = 0;
275	dispDeviceRect[2] = width;
276	dispDeviceRect[3] = height;
277	dispDeviceDepth = depth;
278	dispDeviceRowBytes = pitch;
279	if (boot_text_mapped) {
280		iounmap(logicalDisplayBase);
281		boot_text_mapped = 0;
282	}
283	btext_map();
284	g_loc_X = 0;
285	g_loc_Y = 0;
286	g_max_loc_X = width / 8;
287	g_max_loc_Y = height / 16;
288}
289EXPORT_SYMBOL(btext_update_display);
290
291void __init btext_clearscreen(void)
292{
293	unsigned int *base	= (unsigned int *)calc_base(0, 0);
294	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
295					(dispDeviceDepth >> 3)) >> 2;
296	int i,j;
297
298	rmci_maybe_on();
299	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
300	{
301		unsigned int *ptr = base;
302		for(j=width; j; --j)
303			*(ptr++) = 0;
304		base += (dispDeviceRowBytes >> 2);
305	}
306	rmci_maybe_off();
307}
308
309void __init btext_flushscreen(void)
310{
311	unsigned int *base	= (unsigned int *)calc_base(0, 0);
312	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
313					(dispDeviceDepth >> 3)) >> 2;
314	int i,j;
315
316	for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
317	{
318		unsigned int *ptr = base;
319		for(j = width; j > 0; j -= 8) {
320			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
321			ptr += 8;
322		}
323		base += (dispDeviceRowBytes >> 2);
324	}
325	__asm__ __volatile__ ("sync" ::: "memory");
326}
327
328void __init btext_flushline(void)
329{
330	unsigned int *base	= (unsigned int *)calc_base(0, g_loc_Y << 4);
331	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
332					(dispDeviceDepth >> 3)) >> 2;
333	int i,j;
334
335	for (i=0; i < 16; i++)
336	{
337		unsigned int *ptr = base;
338		for(j = width; j > 0; j -= 8) {
339			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
340			ptr += 8;
341		}
342		base += (dispDeviceRowBytes >> 2);
343	}
344	__asm__ __volatile__ ("sync" ::: "memory");
345}
346
347
348#ifndef NO_SCROLL
349static void scrollscreen(void)
350{
351	unsigned int *src     	= (unsigned int *)calc_base(0,16);
352	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
353	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
354				   (dispDeviceDepth >> 3)) >> 2;
355	int i,j;
356
357	rmci_maybe_on();
358
359	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
360	{
361		unsigned int *src_ptr = src;
362		unsigned int *dst_ptr = dst;
363		for(j=width; j; --j)
364			*(dst_ptr++) = *(src_ptr++);
365		src += (dispDeviceRowBytes >> 2);
366		dst += (dispDeviceRowBytes >> 2);
367	}
368	for (i=0; i<16; i++)
369	{
370		unsigned int *dst_ptr = dst;
371		for(j=width; j; --j)
372			*(dst_ptr++) = 0;
373		dst += (dispDeviceRowBytes >> 2);
374	}
375
376	rmci_maybe_off();
377}
378#endif /* ndef NO_SCROLL */
379
380static unsigned int expand_bits_8[16] = {
381	0x00000000,
382	0x000000ff,
383	0x0000ff00,
384	0x0000ffff,
385	0x00ff0000,
386	0x00ff00ff,
387	0x00ffff00,
388	0x00ffffff,
389	0xff000000,
390	0xff0000ff,
391	0xff00ff00,
392	0xff00ffff,
393	0xffff0000,
394	0xffff00ff,
395	0xffffff00,
396	0xffffffff
397};
398
399static unsigned int expand_bits_16[4] = {
400	0x00000000,
401	0x0000ffff,
402	0xffff0000,
403	0xffffffff
404};
405
406
407static void draw_byte_32(const unsigned char *font, unsigned int *base, int rb)
408{
409	int l, bits;
410	int fg = 0xFFFFFFFFUL;
411	int bg = 0x00000000UL;
412
413	for (l = 0; l < 16; ++l)
414	{
415		bits = *font++;
416		base[0] = (-(bits >> 7) & fg) ^ bg;
417		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
418		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
419		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
420		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
421		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
422		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
423		base[7] = (-(bits & 1) & fg) ^ bg;
424		base = (unsigned int *) ((char *)base + rb);
425	}
426}
427
428static inline void draw_byte_16(const unsigned char *font, unsigned int *base, int rb)
429{
430	int l, bits;
431	int fg = 0xFFFFFFFFUL;
432	int bg = 0x00000000UL;
433	unsigned int *eb = (int *)expand_bits_16;
434
435	for (l = 0; l < 16; ++l)
436	{
437		bits = *font++;
438		base[0] = (eb[bits >> 6] & fg) ^ bg;
439		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
440		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
441		base[3] = (eb[bits & 3] & fg) ^ bg;
442		base = (unsigned int *) ((char *)base + rb);
443	}
444}
445
446static inline void draw_byte_8(const unsigned char *font, unsigned int *base, int rb)
447{
448	int l, bits;
449	int fg = 0x0F0F0F0FUL;
450	int bg = 0x00000000UL;
451	unsigned int *eb = (int *)expand_bits_8;
452
453	for (l = 0; l < 16; ++l)
454	{
455		bits = *font++;
456		base[0] = (eb[bits >> 4] & fg) ^ bg;
457		base[1] = (eb[bits & 0xf] & fg) ^ bg;
458		base = (unsigned int *) ((char *)base + rb);
459	}
460}
461
462static noinline void draw_byte(unsigned char c, long locX, long locY)
463{
464	unsigned char *base	= calc_base(locX << 3, locY << 4);
465	unsigned int font_index = c * 16;
466	const unsigned char *font	= font_sun_8x16.data + font_index;
467	int rb			= dispDeviceRowBytes;
468
469	rmci_maybe_on();
470	switch(dispDeviceDepth) {
471	case 24:
472	case 32:
473		draw_byte_32(font, (unsigned int *)base, rb);
474		break;
475	case 15:
476	case 16:
477		draw_byte_16(font, (unsigned int *)base, rb);
478		break;
479	case 8:
480		draw_byte_8(font, (unsigned int *)base, rb);
481		break;
482	}
483	rmci_maybe_off();
484}
485
486void btext_drawchar(char c)
487{
488	int cline = 0;
489#ifdef NO_SCROLL
490	int x;
491#endif
492	if (!boot_text_mapped)
493		return;
494
495	switch (c) {
496	case '\b':
497		if (g_loc_X > 0)
498			--g_loc_X;
499		break;
500	case '\t':
501		g_loc_X = (g_loc_X & -8) + 8;
502		break;
503	case '\r':
504		g_loc_X = 0;
505		break;
506	case '\n':
507		g_loc_X = 0;
508		g_loc_Y++;
509		cline = 1;
510		break;
511	default:
512		draw_byte(c, g_loc_X++, g_loc_Y);
513	}
514	if (g_loc_X >= g_max_loc_X) {
515		g_loc_X = 0;
516		g_loc_Y++;
517		cline = 1;
518	}
519#ifndef NO_SCROLL
520	while (g_loc_Y >= g_max_loc_Y) {
521		scrollscreen();
522		g_loc_Y--;
523	}
524#else
525	/* wrap around from bottom to top of screen so we don't
526	   waste time scrolling each line.  -- paulus. */
527	if (g_loc_Y >= g_max_loc_Y)
528		g_loc_Y = 0;
529	if (cline) {
530		for (x = 0; x < g_max_loc_X; ++x)
531			draw_byte(' ', x, g_loc_Y);
532	}
533#endif
534}
535
536void btext_drawstring(const char *c)
537{
538	if (!boot_text_mapped)
539		return;
540	while (*c)
541		btext_drawchar(*c++);
542}
543
544void __init btext_drawtext(const char *c, unsigned int len)
545{
546	if (!boot_text_mapped)
547		return;
548	while (len--)
549		btext_drawchar(*c++);
550}
551
552void __init btext_drawhex(unsigned long v)
553{
554	if (!boot_text_mapped)
555		return;
556#ifdef CONFIG_PPC64
557	btext_drawchar(hex_asc_hi(v >> 56));
558	btext_drawchar(hex_asc_lo(v >> 56));
559	btext_drawchar(hex_asc_hi(v >> 48));
560	btext_drawchar(hex_asc_lo(v >> 48));
561	btext_drawchar(hex_asc_hi(v >> 40));
562	btext_drawchar(hex_asc_lo(v >> 40));
563	btext_drawchar(hex_asc_hi(v >> 32));
564	btext_drawchar(hex_asc_lo(v >> 32));
565#endif
566	btext_drawchar(hex_asc_hi(v >> 24));
567	btext_drawchar(hex_asc_lo(v >> 24));
568	btext_drawchar(hex_asc_hi(v >> 16));
569	btext_drawchar(hex_asc_lo(v >> 16));
570	btext_drawchar(hex_asc_hi(v >> 8));
571	btext_drawchar(hex_asc_lo(v >> 8));
572	btext_drawchar(hex_asc_hi(v));
573	btext_drawchar(hex_asc_lo(v));
574	btext_drawchar(' ');
575}
576
577void __init udbg_init_btext(void)
578{
579	/* If btext is enabled, we might have a BAT setup for early display,
580	 * thus we do enable some very basic udbg output
581	 */
582	udbg_putc = btext_drawchar;
583}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Procedures for drawing on the screen early on in the boot process.
  4 *
  5 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
  6 */
  7#include <linux/kernel.h>
  8#include <linux/string.h>
  9#include <linux/init.h>
 10#include <linux/export.h>
 
 11#include <linux/memblock.h>
 12#include <linux/pgtable.h>
 
 13
 14#include <asm/sections.h>
 15#include <asm/prom.h>
 16#include <asm/btext.h>
 17#include <asm/page.h>
 18#include <asm/mmu.h>
 19#include <asm/io.h>
 20#include <asm/processor.h>
 21#include <asm/udbg.h>
 22
 23#define NO_SCROLL
 24
 25#ifndef NO_SCROLL
 26static void scrollscreen(void);
 27#endif
 28
 29#define __force_data __section(".data")
 30
 31static int g_loc_X __force_data;
 32static int g_loc_Y __force_data;
 33static int g_max_loc_X __force_data;
 34static int g_max_loc_Y __force_data;
 35
 36static int dispDeviceRowBytes __force_data;
 37static int dispDeviceDepth  __force_data;
 38static int dispDeviceRect[4] __force_data;
 39static unsigned char *dispDeviceBase __force_data;
 40static unsigned char *logicalDisplayBase __force_data;
 41
 42unsigned long disp_BAT[2] __initdata = {0, 0};
 43
 44#define cmapsz	(16*256)
 45
 46static unsigned char vga_font[cmapsz];
 47
 48int boot_text_mapped __force_data = 0;
 49int force_printk_to_btext = 0;
 50
 51extern void rmci_on(void);
 52extern void rmci_off(void);
 53
 54static inline void rmci_maybe_on(void)
 55{
 56#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 57	if (!(mfmsr() & MSR_DR))
 58		rmci_on();
 59#endif
 60}
 61
 62static inline void rmci_maybe_off(void)
 63{
 64#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 65	if (!(mfmsr() & MSR_DR))
 66		rmci_off();
 67#endif
 68}
 69
 70
 71#ifdef CONFIG_PPC32
 72/* Calc BAT values for mapping the display and store them
 73 * in disp_BAT.  Those values are then used from head.S to map
 74 * the display during identify_machine() and MMU_Init()
 75 *
 76 * The display is mapped to virtual address 0xD0000000, rather
 77 * than 1:1, because some some CHRP machines put the frame buffer
 78 * in the region starting at 0xC0000000 (PAGE_OFFSET).
 79 * This mapping is temporary and will disappear as soon as the
 80 * setup done by MMU_Init() is applied.
 81 *
 82 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
 83 * on other PPCs. This may cause trouble if the framebuffer
 84 * is really badly aligned, but I didn't encounter this case
 85 * yet.
 86 */
 87void __init btext_prepare_BAT(void)
 88{
 89	unsigned long vaddr = PAGE_OFFSET + 0x10000000;
 90	unsigned long addr;
 91	unsigned long lowbits;
 92
 93	addr = (unsigned long)dispDeviceBase;
 94	if (!addr) {
 95		boot_text_mapped = 0;
 96		return;
 97	}
 98	lowbits = addr & ~0xFF000000UL;
 99	addr &= 0xFF000000UL;
100	disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
101	disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
102	logicalDisplayBase = (void *) (vaddr + lowbits);
103}
104#endif
105
106
107/* This function can be used to enable the early boot text when doing
108 * OF booting or within bootx init. It must be followed by a btext_unmap()
109 * call before the logical address becomes unusable
110 */
111void __init btext_setup_display(int width, int height, int depth, int pitch,
112				unsigned long address)
113{
114	g_loc_X = 0;
115	g_loc_Y = 0;
116	g_max_loc_X = width / 8;
117	g_max_loc_Y = height / 16;
118	logicalDisplayBase = (unsigned char *)address;
119	dispDeviceBase = (unsigned char *)address;
120	dispDeviceRowBytes = pitch;
121	dispDeviceDepth = depth == 15 ? 16 : depth;
122	dispDeviceRect[0] = dispDeviceRect[1] = 0;
123	dispDeviceRect[2] = width;
124	dispDeviceRect[3] = height;
125	boot_text_mapped = 1;
126}
127
128void __init btext_unmap(void)
129{
130	boot_text_mapped = 0;
131}
132
133/* Here's a small text engine to use during early boot
134 * or for debugging purposes
135 *
136 * todo:
137 *
138 *  - build some kind of vgacon with it to enable early printk
139 *  - move to a separate file
140 *  - add a few video driver hooks to keep in sync with display
141 *    changes.
142 */
143
144void btext_map(void)
145{
146	unsigned long base, offset, size;
147	unsigned char *vbase;
148
149	/* By default, we are no longer mapped */
150	boot_text_mapped = 0;
151	if (!dispDeviceBase)
152		return;
153	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
154	offset = ((unsigned long) dispDeviceBase) - base;
155	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
156		+ dispDeviceRect[0];
157	vbase = ioremap_wc(base, size);
158	if (!vbase)
159		return;
160	logicalDisplayBase = vbase + offset;
161	boot_text_mapped = 1;
162}
163
164static int btext_initialize(struct device_node *np)
165{
166	unsigned int width, height, depth, pitch;
167	unsigned long address = 0;
168	const u32 *prop;
169
170	prop = of_get_property(np, "linux,bootx-width", NULL);
171	if (prop == NULL)
172		prop = of_get_property(np, "width", NULL);
173	if (prop == NULL)
174		return -EINVAL;
175	width = *prop;
176	prop = of_get_property(np, "linux,bootx-height", NULL);
177	if (prop == NULL)
178		prop = of_get_property(np, "height", NULL);
179	if (prop == NULL)
180		return -EINVAL;
181	height = *prop;
182	prop = of_get_property(np, "linux,bootx-depth", NULL);
183	if (prop == NULL)
184		prop = of_get_property(np, "depth", NULL);
185	if (prop == NULL)
186		return -EINVAL;
187	depth = *prop;
188	pitch = width * ((depth + 7) / 8);
189	prop = of_get_property(np, "linux,bootx-linebytes", NULL);
190	if (prop == NULL)
191		prop = of_get_property(np, "linebytes", NULL);
192	if (prop && *prop != 0xffffffffu)
193		pitch = *prop;
194	if (pitch == 1)
195		pitch = 0x1000;
196	prop = of_get_property(np, "linux,bootx-addr", NULL);
197	if (prop == NULL)
198		prop = of_get_property(np, "address", NULL);
199	if (prop)
200		address = *prop;
201
202	/* FIXME: Add support for PCI reg properties. Right now, only
203	 * reliable on macs
204	 */
205	if (address == 0)
206		return -EINVAL;
207
208	g_loc_X = 0;
209	g_loc_Y = 0;
210	g_max_loc_X = width / 8;
211	g_max_loc_Y = height / 16;
212	dispDeviceBase = (unsigned char *)address;
213	dispDeviceRowBytes = pitch;
214	dispDeviceDepth = depth == 15 ? 16 : depth;
215	dispDeviceRect[0] = dispDeviceRect[1] = 0;
216	dispDeviceRect[2] = width;
217	dispDeviceRect[3] = height;
218
219	btext_map();
220
221	return 0;
222}
223
224int __init btext_find_display(int allow_nonstdout)
225{
226	struct device_node *np = of_stdout;
227	int rc = -ENODEV;
228
229	if (!of_node_is_type(np, "display")) {
230		printk("boot stdout isn't a display !\n");
231		np = NULL;
232	}
233	if (np)
234		rc = btext_initialize(np);
235	if (rc == 0 || !allow_nonstdout)
236		return rc;
237
238	for_each_node_by_type(np, "display") {
239		if (of_get_property(np, "linux,opened", NULL)) {
240			printk("trying %pOF ...\n", np);
241			rc = btext_initialize(np);
242			printk("result: %d\n", rc);
243		}
244		if (rc == 0)
 
245			break;
 
246	}
247	return rc;
248}
249
250/* Calc the base address of a given point (x,y) */
251static unsigned char * calc_base(int x, int y)
252{
253	unsigned char *base;
254
255	base = logicalDisplayBase;
256	if (!base)
257		base = dispDeviceBase;
258	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
259	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
260	return base;
261}
262
263/* Adjust the display to a new resolution */
264void btext_update_display(unsigned long phys, int width, int height,
265			  int depth, int pitch)
266{
267	if (!dispDeviceBase)
268		return;
269
270	/* check it's the same frame buffer (within 256MB) */
271	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
272		return;
273
274	dispDeviceBase = (__u8 *) phys;
275	dispDeviceRect[0] = 0;
276	dispDeviceRect[1] = 0;
277	dispDeviceRect[2] = width;
278	dispDeviceRect[3] = height;
279	dispDeviceDepth = depth;
280	dispDeviceRowBytes = pitch;
281	if (boot_text_mapped) {
282		iounmap(logicalDisplayBase);
283		boot_text_mapped = 0;
284	}
285	btext_map();
286	g_loc_X = 0;
287	g_loc_Y = 0;
288	g_max_loc_X = width / 8;
289	g_max_loc_Y = height / 16;
290}
291EXPORT_SYMBOL(btext_update_display);
292
293void btext_clearscreen(void)
294{
295	unsigned int *base	= (unsigned int *)calc_base(0, 0);
296	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
297					(dispDeviceDepth >> 3)) >> 2;
298	int i,j;
299
300	rmci_maybe_on();
301	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
302	{
303		unsigned int *ptr = base;
304		for(j=width; j; --j)
305			*(ptr++) = 0;
306		base += (dispDeviceRowBytes >> 2);
307	}
308	rmci_maybe_off();
309}
310
311void btext_flushscreen(void)
312{
313	unsigned int *base	= (unsigned int *)calc_base(0, 0);
314	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
315					(dispDeviceDepth >> 3)) >> 2;
316	int i,j;
317
318	for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
319	{
320		unsigned int *ptr = base;
321		for(j = width; j > 0; j -= 8) {
322			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
323			ptr += 8;
324		}
325		base += (dispDeviceRowBytes >> 2);
326	}
327	__asm__ __volatile__ ("sync" ::: "memory");
328}
329
330void btext_flushline(void)
331{
332	unsigned int *base	= (unsigned int *)calc_base(0, g_loc_Y << 4);
333	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
334					(dispDeviceDepth >> 3)) >> 2;
335	int i,j;
336
337	for (i=0; i < 16; i++)
338	{
339		unsigned int *ptr = base;
340		for(j = width; j > 0; j -= 8) {
341			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
342			ptr += 8;
343		}
344		base += (dispDeviceRowBytes >> 2);
345	}
346	__asm__ __volatile__ ("sync" ::: "memory");
347}
348
349
350#ifndef NO_SCROLL
351static void scrollscreen(void)
352{
353	unsigned int *src     	= (unsigned int *)calc_base(0,16);
354	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
355	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
356				   (dispDeviceDepth >> 3)) >> 2;
357	int i,j;
358
359	rmci_maybe_on();
360
361	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
362	{
363		unsigned int *src_ptr = src;
364		unsigned int *dst_ptr = dst;
365		for(j=width; j; --j)
366			*(dst_ptr++) = *(src_ptr++);
367		src += (dispDeviceRowBytes >> 2);
368		dst += (dispDeviceRowBytes >> 2);
369	}
370	for (i=0; i<16; i++)
371	{
372		unsigned int *dst_ptr = dst;
373		for(j=width; j; --j)
374			*(dst_ptr++) = 0;
375		dst += (dispDeviceRowBytes >> 2);
376	}
377
378	rmci_maybe_off();
379}
380#endif /* ndef NO_SCROLL */
381
382static unsigned int expand_bits_8[16] = {
383	0x00000000,
384	0x000000ff,
385	0x0000ff00,
386	0x0000ffff,
387	0x00ff0000,
388	0x00ff00ff,
389	0x00ffff00,
390	0x00ffffff,
391	0xff000000,
392	0xff0000ff,
393	0xff00ff00,
394	0xff00ffff,
395	0xffff0000,
396	0xffff00ff,
397	0xffffff00,
398	0xffffffff
399};
400
401static unsigned int expand_bits_16[4] = {
402	0x00000000,
403	0x0000ffff,
404	0xffff0000,
405	0xffffffff
406};
407
408
409static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
410{
411	int l, bits;
412	int fg = 0xFFFFFFFFUL;
413	int bg = 0x00000000UL;
414
415	for (l = 0; l < 16; ++l)
416	{
417		bits = *font++;
418		base[0] = (-(bits >> 7) & fg) ^ bg;
419		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
420		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
421		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
422		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
423		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
424		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
425		base[7] = (-(bits & 1) & fg) ^ bg;
426		base = (unsigned int *) ((char *)base + rb);
427	}
428}
429
430static inline void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
431{
432	int l, bits;
433	int fg = 0xFFFFFFFFUL;
434	int bg = 0x00000000UL;
435	unsigned int *eb = (int *)expand_bits_16;
436
437	for (l = 0; l < 16; ++l)
438	{
439		bits = *font++;
440		base[0] = (eb[bits >> 6] & fg) ^ bg;
441		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
442		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
443		base[3] = (eb[bits & 3] & fg) ^ bg;
444		base = (unsigned int *) ((char *)base + rb);
445	}
446}
447
448static inline void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
449{
450	int l, bits;
451	int fg = 0x0F0F0F0FUL;
452	int bg = 0x00000000UL;
453	unsigned int *eb = (int *)expand_bits_8;
454
455	for (l = 0; l < 16; ++l)
456	{
457		bits = *font++;
458		base[0] = (eb[bits >> 4] & fg) ^ bg;
459		base[1] = (eb[bits & 0xf] & fg) ^ bg;
460		base = (unsigned int *) ((char *)base + rb);
461	}
462}
463
464static noinline void draw_byte(unsigned char c, long locX, long locY)
465{
466	unsigned char *base	= calc_base(locX << 3, locY << 4);
467	unsigned char *font	= &vga_font[((unsigned int)c) * 16];
 
468	int rb			= dispDeviceRowBytes;
469
470	rmci_maybe_on();
471	switch(dispDeviceDepth) {
472	case 24:
473	case 32:
474		draw_byte_32(font, (unsigned int *)base, rb);
475		break;
476	case 15:
477	case 16:
478		draw_byte_16(font, (unsigned int *)base, rb);
479		break;
480	case 8:
481		draw_byte_8(font, (unsigned int *)base, rb);
482		break;
483	}
484	rmci_maybe_off();
485}
486
487void btext_drawchar(char c)
488{
489	int cline = 0;
490#ifdef NO_SCROLL
491	int x;
492#endif
493	if (!boot_text_mapped)
494		return;
495
496	switch (c) {
497	case '\b':
498		if (g_loc_X > 0)
499			--g_loc_X;
500		break;
501	case '\t':
502		g_loc_X = (g_loc_X & -8) + 8;
503		break;
504	case '\r':
505		g_loc_X = 0;
506		break;
507	case '\n':
508		g_loc_X = 0;
509		g_loc_Y++;
510		cline = 1;
511		break;
512	default:
513		draw_byte(c, g_loc_X++, g_loc_Y);
514	}
515	if (g_loc_X >= g_max_loc_X) {
516		g_loc_X = 0;
517		g_loc_Y++;
518		cline = 1;
519	}
520#ifndef NO_SCROLL
521	while (g_loc_Y >= g_max_loc_Y) {
522		scrollscreen();
523		g_loc_Y--;
524	}
525#else
526	/* wrap around from bottom to top of screen so we don't
527	   waste time scrolling each line.  -- paulus. */
528	if (g_loc_Y >= g_max_loc_Y)
529		g_loc_Y = 0;
530	if (cline) {
531		for (x = 0; x < g_max_loc_X; ++x)
532			draw_byte(' ', x, g_loc_Y);
533	}
534#endif
535}
536
537void btext_drawstring(const char *c)
538{
539	if (!boot_text_mapped)
540		return;
541	while (*c)
542		btext_drawchar(*c++);
543}
544
545void btext_drawtext(const char *c, unsigned int len)
546{
547	if (!boot_text_mapped)
548		return;
549	while (len--)
550		btext_drawchar(*c++);
551}
552
553void btext_drawhex(unsigned long v)
554{
555	if (!boot_text_mapped)
556		return;
557#ifdef CONFIG_PPC64
558	btext_drawchar(hex_asc_hi(v >> 56));
559	btext_drawchar(hex_asc_lo(v >> 56));
560	btext_drawchar(hex_asc_hi(v >> 48));
561	btext_drawchar(hex_asc_lo(v >> 48));
562	btext_drawchar(hex_asc_hi(v >> 40));
563	btext_drawchar(hex_asc_lo(v >> 40));
564	btext_drawchar(hex_asc_hi(v >> 32));
565	btext_drawchar(hex_asc_lo(v >> 32));
566#endif
567	btext_drawchar(hex_asc_hi(v >> 24));
568	btext_drawchar(hex_asc_lo(v >> 24));
569	btext_drawchar(hex_asc_hi(v >> 16));
570	btext_drawchar(hex_asc_lo(v >> 16));
571	btext_drawchar(hex_asc_hi(v >> 8));
572	btext_drawchar(hex_asc_lo(v >> 8));
573	btext_drawchar(hex_asc_hi(v));
574	btext_drawchar(hex_asc_lo(v));
575	btext_drawchar(' ');
576}
577
578void __init udbg_init_btext(void)
579{
580	/* If btext is enabled, we might have a BAT setup for early display,
581	 * thus we do enable some very basic udbg output
582	 */
583	udbg_putc = btext_drawchar;
584}
585
586static unsigned char vga_font[cmapsz] = {
5870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
5890x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
5900xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
5910x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
5920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
5930x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
5940x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
5950x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
5960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5970x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
5980xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5990x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
6000x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
6010xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
6020x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
6030x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
6040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
6050x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
6060x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
6070x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
6080x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
6090xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
6100x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
6110x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
6120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
6130x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
6140xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
6150x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
6160x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6170xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
6180x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
6190x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
6200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
6210x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6220x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6230x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
6240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
6250xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6260x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6270x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
6280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
6290x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6310x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
6320x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
6330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
6340x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
6350x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
6360x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
6370x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
6380x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6390x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
6410x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
6420x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
6430x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
6440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
6450x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6460x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
6470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
6480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6490x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6500x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
6510x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
6520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
6530x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6540x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
6550x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
6560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
6570x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
6580xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6590x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
6610x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6620xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6630x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
6640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
6650x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6660x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
6670x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
6680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
6690x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
6700x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
6710x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
6720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
6730xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
6740x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
6750x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
6760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
6770xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
6780x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
6790x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
6800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
6810x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6820xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
6830x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
6850x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
6860x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
6870x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
6880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
6890x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
6900xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
6910x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
6920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6930xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
6940x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
6950x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
6960x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
6970x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6980xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6990x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
7010xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
7020xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
7030x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
7040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
7050x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
7060xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7070x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
7080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
7090x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
7100xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
7110x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
7120x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
7130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
7150x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
7170xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
7180x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
7190x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
7200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
7210xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7220x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7230x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
7240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
7250xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
7260x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
7270x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
7290x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
7300x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
7310x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
7330xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7340x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
7350x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
7370x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
7380x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
7390x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
7400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
7410x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
7420x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
7430x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
7450xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7460x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
7470x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
7480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
7490xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
7500x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
7510x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
7520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
7530x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
7540x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
7550x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
7570xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
7580xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
7590x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7600x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
7610xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
7620x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
7630x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
7640x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
7650xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
7660x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
7670x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
7680x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
7690xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7700x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7710x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
7720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
7730x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
7740x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7750x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7760x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
7770xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
7780x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
7790x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
7800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
7810x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
7820xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
7830x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
7850xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
7860x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7870x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7880x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
7890xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7900x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
7910x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7920x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
7930xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
7940xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
7950x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
7960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
7970xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
7980x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
7990x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
8000xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
8010xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
8020x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
8030x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
8040x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
8050xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
8060x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
8070x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
8080x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
8090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
8100x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8110x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
8120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
8130xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8140x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
8150x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
8160x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
8170x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
8180x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
8190x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
8200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
8210x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
8220x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
8230x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
8240x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
8250xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
8260x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8270x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
8280x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
8290x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
8300x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
8320x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
8330x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
8340x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8350x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8360x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
8370x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8380x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8390x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
8400x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
8410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8420x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8430x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
8440x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
8450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8460x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8470x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8480x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
8500x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8510x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8520x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
8530x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8540x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8550x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
8560x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
8570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8580x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8590x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
8600x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
8610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
8620x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8630x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
8640x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
8650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8660x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
8680x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
8690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
8700x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8710x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8720x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
8730x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8740x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8750x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
8760x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
8770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8780x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8800xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
8820xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
8830x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
8840x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
8850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8860x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
8870x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
8880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
8890xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8900xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
8910x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
8920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
8930xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8940x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
8950x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
8970x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
8980x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
8990x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
9000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
9010x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9020x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9030x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
9040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
9050x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
9060xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
9070x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
9080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
9090x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
9100x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
9110x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
9120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
9130x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
9140x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
9150x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
9160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
9170x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
9180x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
9200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9210x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
9220x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
9230x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
9240x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
9250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9260x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
9270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9280x00, 0x00, 0x00, 0x00,
929};
930