Displaylink proof-of-concept demo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello everyone,

I'm happy to announce that Chris and I have made significant progress
over the holidays with respect to driving DisplayLink devices. For an
overview of the commands etc., see
http://floe.butterbrot.org/displaylink/

I'm attaching the source code for a short "demo" of the features which
are already working. These are basically

- initialization of standard video modes @ 60Hz (640x480, 800x600 .. )
- writing raw data to the framebuffer
- writing RLE-compressed data
- basic blitting
- vertical scrolling through a larger framebuffer

It would be very helpful if some adventurous people who have a
DL-120-based DisplayLink device could give it a try. I have no idea how
a DL-160-based device will react; but if you are _really_ adventurous,
go ahead :-) If you have a 640x960 pixel RGB raw image, you can pass it
as first parameter; otherwise, it will use a red gradient.

So far for things which work, here are the things which still don't (in
increasing order of importance):

- horizontal scrolling
- fine-tuning of video mode (pixel clock etc. - this is hidden somewhere
  in the first block of registers)
- compressed pixel data (I haven't been able to really figure out what
  kind of compression this is. I think it might be a Huffman code, but
  that's just a wild guess. However, I'm pretty sure that the bit order
  in the bytes of the compressed stream should be reversed to get the
  original bitstream. And the big binary block inside the demo program
  is perhaps the Huffman code table.)

So far from me, I'm very much hoping that some of you can give some
additional feedback.

Yours, Florian
/*
 * displaylink userspace controller demo 0.0.1
 * written 2008/09 by floe at butterbrot.org
 * in cooperation with chrisly at platon42.de
 * this code is released as public domain.
 *
 * this is so experimental that the warranty shot itself.
 * so don't expect any.
 *
 * build with "g++ -ggdb -Wall -o displaylink displaylink.c -lusb"
 *
 */

#include <usb.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


/******************* ENCRYPTION STUFF **********************/

unsigned char nullkey1[] = { 0x57, 0xCD, 0xDC, 0xA7, 0x1C, 0x88, 0x5E, 0x15, 0x60, 0xFE, 0xC6, 0x97, 0x16, 0x3D, 0x47, 0xF2 };
unsigned char nullkey2[] = { 0x47, 0x3D, 0x16, 0x97, 0xC6, 0xFE, 0x60, 0x15, 0x5E, 0x88, 0x1C, 0xA7, 0xDC, 0xB7, 0x6F, 0xF2 };
unsigned char nullkey3[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x18,0xF0 };

uint8_t  keybuffer[0x11000];
uint16_t ofsbuffer[0x1000];

// x^12+x^11+x^3+x^2+x+1 = 0001 1000 0000 1111 = 0x180F
int dl_crc12( unsigned char* data, int len) {
	int rem = 0;
	for (int i = 0; i < len; i++) {
		for (int j = 0; j < 8; j++) {
			rem = (rem << 1) | ((data[i] >> j) & 0x01);
			if (rem & 0x1000) rem = rem ^ 0x180F;
		}
	}
	return rem;
}


void dl_generate_key( uint8_t key[0x11000], uint16_t map[0x1000] ) {

  int coeffs[0x20];
  int count = 0;

  // loop1:
  for (int i = 0; i < 0x20; i++) {

    int tmp = 1 << i;
    if (!(tmp & 0x0829)) continue;

    coeffs[count] = i;
    count++;
  }

  int val = 0x01;

  // loop2:
  for (int i = 0; i < 0x11000; i++) {

    key[i] = val;
    if (i < 0x1000) map[val] = i;

    // loop3:
    for ( int j = 8; j > 0; j--) {

      int res = 0;

			// loop4:
      for (int k = 0; k < count; k++) {
        int coeff = coeffs[k];
        coeff = val >> coeff;
        res = res ^ coeff;
      }

      res = res & 1;
      res = res ^ (2*val);
      val = res & 0xFFF;
    }
  }
}


/******************* INITIALIZATION STUFF *****************/

uint8_t dl_peek( int addr, usb_dev_handle* handle, int timeout = 1000 ) {
	uint8_t buf[1];
	usb_control_msg( handle, 0xC0, 0x04, 0x00, addr, (char*)buf, 1, timeout );
	return buf[0];
}

void dl_poke( int addr, uint8_t value, usb_dev_handle* handle, int timeout = 1000 ) {
	usb_control_msg( handle, 0x40, 0x03, 0x00, addr, (char*)&value, 1, timeout );
}

int dl_poll( usb_dev_handle* handle, int timeout = 1000 ) {
	uint8_t buf[4];
	usb_control_msg( handle, 0xC0, 0x06, 0x00, 0x00, (char*)buf, 4, timeout );
	return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
}

void dl_set_key( uint8_t key[16], usb_dev_handle* handle, int timeout = 1000 ) {
	usb_control_msg( handle, 0x40, 0x12, 0x00, 0x00, (char*)key, 16, timeout );
}

void dl_blink( usb_dev_handle* handle, int timeout = 1000 ) {
	usb_control_msg( handle, 0x40, 0x14, 0x00, 0x00, NULL, 0, timeout );
}

void dl_get_edid( uint8_t edid[128], usb_dev_handle* handle, int timeout = 1000 ) {
	uint8_t buf[64];
	int offset = 0;
	usb_control_msg( handle, 0xC0, 0x02, offset<<8, 0xA1, (char*)buf, 64, timeout ); memcpy( edid+offset, buf+1, 63 ); offset += 63;
	usb_control_msg( handle, 0xC0, 0x02, offset<<8, 0xA1, (char*)buf, 64, timeout ); memcpy( edid+offset, buf+1, 63 ); offset += 63;
	usb_control_msg( handle, 0xC0, 0x02, offset<<8, 0xA1, (char*)buf,  3, timeout ); memcpy( edid+offset, buf+1,  2 ); 
}

/******************* COMMAND BUFFER ***********************/

typedef struct {
	uint8_t* buffer;
	int pos, size;
} dl_cmdstream;


inline void create( dl_cmdstream* cs, int size ) {
	cs->buffer = (uint8_t*)malloc( size );
	cs->size = size;
	cs->pos = 0;
}

inline void destroy( dl_cmdstream* cs ) {
	free( cs->buffer );
	cs->size = 0;
}

inline void send( dl_cmdstream* cs, usb_dev_handle* handle, int ep = 1, int timeout = 1000 ) {
	usb_bulk_write( handle, ep, (char*)cs->buffer, cs->pos, timeout );
	cs->pos = 0;
}

inline void insertb( dl_cmdstream* cs, uint8_t val ) {
	cs->buffer[cs->pos++] = val;
}

inline void insertw( dl_cmdstream* cs, uint16_t val ) {
	insertb( cs, (val >> 8) & 0xFF );
	insertb( cs, (val     ) & 0xFF );
}

inline void inserta( dl_cmdstream* cs, uint32_t address ) {
	insertb( cs, (address >> 16) & 0xFF );
	insertb( cs, (address >>  8) & 0xFF );
	insertb( cs, (address      ) & 0xFF );
}

inline void insertd( dl_cmdstream* cs, uint32_t val ) {
	insertb( cs, (val >> 24) & 0xFF );
	insertb( cs, (val >> 16) & 0xFF );
	insertb( cs, (val >>  8) & 0xFF );
	insertb( cs, (val      ) & 0xFF );
}

inline void insert( dl_cmdstream* cs, int size, uint8_t* buf ) {
	memcpy( cs->buffer+cs->pos, buf, size );
	cs->pos += size;
}


/******************* COMMANDS *****************************/

#define DL_SOC 0xAF // start-of-command token


/******************* MISC COMMANDS ************************/

void dl_unknown_command( dl_cmdstream* cs ) {
	insertb( cs, DL_SOC );
	insertb( cs,   0x40 );
	insertb( cs,   0x0B );
}

void dl_sync_command( dl_cmdstream* cs ) {
	insertb( cs, DL_SOC );
	insertb( cs,   0xA0 );
}

void dl_decomp_table_command( dl_cmdstream* cs, int size, uint8_t* buf ) {

	if ((size % 9) != 0) return;
	int count = size / 9;

	insertb( cs, DL_SOC );
	insertb( cs,   0xE0 );

	insertd( cs, 0x263871CD ); // magic number
 	insertd( cs, count );      // count of 9-byte chunks

	insert( cs, size, buf );   // count * 9 bytes

	dl_sync_command( cs );
}


/******************* REGISTER COMMANDS ********************/

#define DL_REG_COLORDEPTH   0x00 // 0 = 16 bit, 1 = 24 bit
// 0x01 - 0x0E unknown
#define DL_REG_XRES_MSB     0x0F
#define DL_REG_XRES_LSB     0x10
// 0x11 - 0x16 unknown
#define DL_REG_YRES_MSB     0x17
#define DL_REG_YRES_LSB     0x18
// 0x19 - 0x1C unknown
// 0x1D - 0x1E unused
#define DL_REG_BLANK_SCREEN 0x1F // 0 = normal operation, 1 = blank screen
// 0x20 - 0xFE unused
#define DL_REG_SYNC         0xFF // 0 = hold register updates, 0xFF = resume

// The unknown registers very likely contain pixel clock, sync polarity etc.
// While the mapping hasn't been found yet, some default register sets for 
// standard resolutions are given below.

uint8_t dl_register_init_640[]  = { 0x00, 0x99, 0x30, 0x26, 0x94, 0x60, 0xa9, 0xce, 0x60, 0x07, 0xb3, 0x0f, 0x79, 0xff, 0xff, 0x02, 0x80, 0x83, 0xbc, 0xff, 0xfc, 0xff, 0xff, 0x01, 0xe0, 0x01, 0x02, 0xab, 0x13 };
uint8_t dl_register_init_800[]  = { 0x00, 0x20, 0x3c, 0x7a, 0xc9, 0x93, 0x60, 0xc8, 0xc7, 0x70, 0x53, 0xff, 0xff, 0x21, 0x27, 0x03, 0x20, 0x91, 0x8f, 0xff, 0xff, 0xff, 0xf2, 0x02, 0x58, 0x01, 0x02, 0x40, 0x1f };
uint8_t dl_register_init_1024[] = { 0x00, 0x36, 0x18, 0xd5, 0x10, 0x60, 0xa9, 0x7b, 0x33, 0xa1, 0x2b, 0x27, 0x32, 0xff, 0xff, 0x04, 0x00, 0xd9, 0x9a, 0xff, 0xca, 0xff, 0xff, 0x03, 0x00, 0x04, 0x03, 0xc8, 0x32 };
uint8_t dl_register_init_1280[] = { 0x00, 0x98, 0xf8, 0x0d, 0x57, 0x2a, 0x55, 0x4d, 0x54, 0xca, 0x0d, 0xff, 0xff, 0x94, 0x43, 0x05, 0x00, 0x9a, 0xa8, 0xff, 0xff, 0xff, 0xf9, 0x04, 0x00, 0x04, 0x02, 0x60, 0x54 };

/*24-bit:
640x480:    01    99 30 26 94 60 a9 ce 60 07 b3 0f 79 ff ff  02 80  83 bc ff fc ff ff  01 e0  01 02 ab 13 
1280x..:    01    98 f8 0d 57 2a 55 4d 54 ca 0d ff ff 94 43  05 00  9a a8 ff ff ff f9  04 00  04 02 60 54 
*/

void dl_set_register( dl_cmdstream* cs, uint8_t reg, uint8_t val ) {
	insertb( cs, DL_SOC );
	insertb( cs,   0x20 );
	insertb( cs,    reg );
	insertb( cs,    val );
}

void dl_set_registers( dl_cmdstream* cs, uint8_t values[0x1D] ) {
	dl_set_register( cs, DL_REG_SYNC, 0x00 );
	for (int i = 0; i < 0x1D; i++)
		dl_set_register( cs, i, values[i] );
	dl_set_register( cs, DL_REG_SYNC, 0xFF );
}


/****************** ADDRESS REGISTERS *********************/

#define DL_ADDR_FB16_START  0x20 // 16-bit mode, color MSBs, RGB 565
#define DL_ADDR_FB16_STRIDE 0x23
#define DL_ADDR_FB8_START   0x26 // additional 8 bit for 24-bit mode, color LSBs, RGB 323?
#define DL_ADDR_FB8_STRIDE  0x29

void dl_set_address( dl_cmdstream* cs, uint8_t reg, int address ) {
	dl_set_register( cs, reg+0, (address >> 16) & 0xFF );
	dl_set_register( cs, reg+1, (address >>  8) & 0xFF );
	dl_set_register( cs, reg+2, (address      ) & 0xFF );
}

void dl_set_offsets( dl_cmdstream* cs, int start16, int stride16, int start8, int stride8 ) {
	dl_set_register( cs, DL_REG_SYNC, 0x00 );
	dl_set_address( cs, DL_ADDR_FB16_START,  start16  );
	dl_set_address( cs, DL_ADDR_FB16_STRIDE, stride16 );
	dl_set_address( cs, DL_ADDR_FB8_START,   start8   );
	dl_set_address( cs, DL_ADDR_FB8_STRIDE,  stride8  );
	dl_set_register( cs, DL_REG_SYNC, 0xFF );
}


/******************* GRAPHICS COMMANDS ********************/

#define DL_GFX_BASE 0x60 // base graphics command
#define DL_GFX_WORD 0x08 // word-mode flag
#define DL_GFX_COMP 0x10 // compressed-mode flag

#define DL_GFX_WRITE (DL_GFX_BASE | 0x00) // write memory
#define DL_GFX_RLE   (DL_GFX_BASE | 0x01) // write RLE-encoded data
#define DL_GFX_COPY  (DL_GFX_BASE | 0x02) // internal copy

void dl_gfx_command( dl_cmdstream* cs, uint8_t cmd, int addr, uint8_t count ) {
	insertb( cs, DL_SOC );
	insertb( cs,    cmd );
	inserta( cs,   addr );
	insertb( cs,  count );
}

void dl_gfx_write( dl_cmdstream* cs, int addr, uint8_t count, uint8_t* data ) {
	dl_gfx_command( cs, DL_GFX_WRITE | DL_GFX_WORD, addr, count );
	int pcount = (count == 0) ? 256 : count;
	insert( cs, pcount*2, data );
}

typedef struct {
	uint8_t count;
	uint16_t value;
} rle_word;

void dl_gfx_rle( dl_cmdstream* cs, int addr, uint8_t count, rle_word* rs ) {

	dl_gfx_command( cs, DL_GFX_RLE | DL_GFX_WORD, addr, count );

	int pcount = (count == 0) ? 256 : count;
	int i = 0;
	rle_word* cur = rs;

	while (i < pcount) {
		insertb( cs, cur->count );
		insertw( cs, cur->value );
		i += (cur->count == 0) ? 256: cur->count;
		cur++;
	}
}

void dl_gfx_copy( dl_cmdstream* cs, int src_addr, int dst_addr, uint8_t count ) {
	dl_gfx_command( cs, DL_GFX_COPY | DL_GFX_WORD, dst_addr, count );
  inserta( cs, src_addr );
}


/******************* INITIALIZATION SEQUENCE **************/

static uint8_t dl_decomp_table[] = {
	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, 0x61,
	0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x60, 0x05, 0x00, 0x00, 0x00, 0x61,
	0x00, 0x00, 0x00, 0x01, 0x67, 0x00, 0x01, 0x00, 0x01,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0x00, 0x00, 0x00, 0x01, 0x89, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x00, 0x61, 0xab, 0x00, 0x00, 0x00, 0x61,
	0x00, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x60, 0x0f, 0x00, 0x00, 0x00, 0x61,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x01, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02,
	0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x00, 0x01, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02,
	0x00, 0x00, 0x01, 0x01, 0x2b, 0x00, 0x00, 0x01, 0x02,
	0x00, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x02, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0xdd, 0x00, 0x04, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x02, 0xef, 0x00, 0x00, 0x00, 0x02,
	0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x01, 0x01, 0xc4, 0x00, 0x00, 0x01, 0x03,
	0x00, 0x29, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03,
	0x00, 0xb7, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0x99, 0x00, 0x04, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0xaa, 0x00, 0x08, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0xbc, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0xde, 0x00, 0x00, 0x00, 0x03,
	0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0x56, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0x9a, 0x00, 0x00, 0x00, 0x04,
	0x00, 0xd7, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x02, 0x01,
	0x00, 0x00, 0x02, 0x04, 0xbb, 0x00, 0x00, 0x03, 0x04,
	0x00, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x08, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0xdd, 0x00, 0x10, 0x00, 0x04,
	0x00, 0x20, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0x05,
	0xff, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,
	0x00, 0x00, 0x00, 0x05, 0x23, 0x00, 0x00, 0x00, 0x05,
	0x08, 0x00, 0x01, 0x00, 0x00, 0x08, 0x20, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x05, 0x45, 0x00, 0x00, 0x00, 0x05,
	0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x05, 0x67, 0x00, 0x00, 0x00, 0x05,
	0xf8, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xe0, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x05, 0x89, 0x00, 0x00, 0x00, 0x05,
	0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xdf, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x05, 0xab, 0x00, 0x00, 0x00, 0x05,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x02, 0x01,
	0x00, 0x00, 0x02, 0x05, 0xcc, 0x00, 0x00, 0x03, 0x05,
	0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x32, 0x01, 0x00,
	0x00, 0xce, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x05, 0xde, 0x00, 0x00, 0x00, 0x05,
	0x00, 0x00, 0x00, 0x05, 0xff, 0x00, 0x10, 0x00, 0x05,
	0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x20, 0x00, 0x06,
	0x08, 0x41, 0x01, 0x00, 0x00, 0x08, 0x21, 0x01, 0x00,
	0x08, 0x61, 0x00, 0x06, 0x12, 0x00, 0x00, 0x00, 0x06,
	0x00, 0x00, 0x00, 0x06, 0x34, 0x00, 0x00, 0x00, 0x06,
	0xf7, 0xbf, 0x01, 0x00, 0x00, 0xf7, 0xdf, 0x01, 0x00,
	0xf7, 0x9f, 0x00, 0x06, 0x56, 0x00, 0x00, 0x00, 0x06,
	0x00, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x06,
	0x10, 0x61, 0x00, 0x06, 0x9a, 0x00, 0x00, 0x00, 0x06,
	0x00, 0x41, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x06,
	0x08, 0x62, 0x00, 0x06, 0x9c, 0x00, 0x00, 0x00, 0x06,
	0x08, 0x40, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x00, 0x06,
	0xef, 0x9f, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x06,
	0xff, 0xbf, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x07,
	0xf7, 0x9e, 0x00, 0x06, 0xe1, 0x00, 0x00, 0x00, 0x07,
	0xf7, 0xc0, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x07,
	0x00, 0x00, 0x00, 0x07, 0x34, 0x00, 0x00, 0x00, 0x07,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x03, 0x01,
	0x00, 0x00, 0x04, 0x07, 0x55, 0x00, 0x00, 0x06, 0x07,
	0x00, 0x00, 0x00, 0x07, 0x66, 0x00, 0x20, 0x00, 0x07,
	0x00, 0x00, 0x00, 0x07, 0x77, 0x00, 0x40, 0x00, 0x07,
	0x00, 0x00, 0x00, 0x07, 0x88, 0x00, 0x20, 0x00, 0x07,
	0x08, 0x01, 0x01, 0x00, 0x09, 0x10, 0x02, 0x00, 0x07,
	0xef, 0xfe, 0x00, 0x07, 0xab, 0x00, 0x00, 0x00, 0x07,
	0x00, 0x00, 0x00, 0x07, 0xcf, 0xff, 0xff, 0xff, 0x7f,
	0x00, 0x00, 0x00, 0x07, 0xdd, 0xff, 0xe0, 0x00, 0x07,
	0xf7, 0xff, 0x01, 0x00, 0x0e, 0xef, 0xfe, 0x00, 0x07,
	0x10, 0x02, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x00, 0x08, 0x1f, 0xff, 0xff, 0xff, 0x7f,
	0x00, 0x00, 0x01, 0x00, 0x02, 0x08, 0x41, 0x00, 0x08,
	0x10, 0x41, 0x00, 0x06, 0x93, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x00, 0x08, 0x45, 0x00, 0x00, 0x00, 0x08,
	0x08, 0x42, 0x00, 0x06, 0x96, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x08,
	0xef, 0xbf, 0x00, 0x06, 0xea, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x00, 0x08, 0xbc, 0x00, 0x00, 0x00, 0x08,
	0xf7, 0xbe, 0x00, 0x06, 0xed, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x00, 0x08, 0xef, 0x00, 0x00, 0x00, 0x08,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x03, 0x01,
	0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x00, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x33, 0x00, 0x40, 0x00, 0x09,
	0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00,
	0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x55, 0x08, 0x01, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x66, 0xf7, 0xff, 0x00, 0x09,
	0x10, 0x42, 0x00, 0x06, 0x99, 0x10, 0x62, 0x00, 0x06,
	0xf8, 0x1f, 0x00, 0x06, 0x99, 0x00, 0x40, 0x00, 0x06,
	0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x88, 0xf7, 0xff, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0x99, 0x08, 0x01, 0x00, 0x09,
	0xef, 0xbe, 0x00, 0x06, 0xee, 0xef, 0x9e, 0x00, 0x06,
	0x07, 0xe1, 0x00, 0x06, 0xee, 0xff, 0xc0, 0x00, 0x06,
	0x00, 0x00, 0x01, 0x00, 0x0a, 0x08, 0x41, 0x00, 0x09,
	0xf8, 0x20, 0x00, 0x06, 0x99, 0x07, 0xff, 0x00, 0x06,
	0x08, 0x1f, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0xcd, 0x00, 0x00, 0x00, 0x09,
	0x00, 0x1f, 0x00, 0x06, 0x99, 0xf8, 0x01, 0x00, 0x06,
	0xf8, 0x21, 0x00, 0x06, 0x9e, 0x00, 0x00, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x0a,
	0x07, 0xe0, 0x00, 0x06, 0xee, 0xf8, 0x01, 0x00, 0x06,
	0xf7, 0xe1, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0x34, 0x00, 0x00, 0x00, 0x0a,
	0xff, 0xe1, 0x00, 0x06, 0xee, 0x07, 0xff, 0x00, 0x06,
	0x07, 0xdf, 0x00, 0x06, 0xe5, 0x00, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0x67, 0x00, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0x89, 0x00, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x05, 0x01,
	0x00, 0x00, 0x08, 0x0a, 0xaa, 0x00, 0x00, 0x0c, 0x0a,
	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
	0x00, 0x00, 0x00, 0x0a, 0xbb, 0x08, 0x41, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0xcd, 0x10, 0x02, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0xce, 0xef, 0xfe, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0a, 0xff, 0xf7, 0xbf, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0b, 0x01, 0xef, 0xfe, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0b, 0x02, 0x10, 0x02, 0x00, 0x0b,
	0x00, 0x00, 0x01, 0x00, 0x03, 0x08, 0x41, 0x00, 0x0b,
	0x10, 0x21, 0x00, 0x06, 0x94, 0x00, 0x00, 0x00, 0x0b,
	0xef, 0xff, 0x00, 0x06, 0x95, 0x00, 0x00, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0b, 0x66, 0x00, 0x20, 0x00, 0x0b,
	0x08, 0x22, 0x00, 0x06, 0x97, 0x00, 0x00, 0x00, 0x0b,
	0xf7, 0xfe, 0x00, 0x06, 0x98, 0x00, 0x00, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0b, 0x99, 0x00, 0x20, 0x00, 0x0b,
	0x00, 0x00, 0x01, 0x00, 0x0a, 0xf7, 0xbf, 0x00, 0x0b,
	0xef, 0xdf, 0x00, 0x06, 0xeb, 0x00, 0x00, 0x00, 0x0b,
	0x10, 0x01, 0x00, 0x06, 0xec, 0x00, 0x00, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0b, 0xdd, 0xff, 0xe0, 0x00, 0x0b,
	0xf7, 0xde, 0x00, 0x06, 0xee, 0x00, 0x00, 0x00, 0x0b,
	0x08, 0x02, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xe0, 0x00, 0x0c,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x05, 0x01,
	0x00, 0x00, 0x08, 0x0c, 0x11, 0x00, 0x00, 0x0c, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0x23, 0x00, 0x00, 0x00, 0x0c,
	0x00, 0x00, 0x01, 0x00, 0x04, 0x10, 0x82, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0x56, 0x00, 0x00, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0x77, 0x10, 0x02, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0x88, 0xef, 0xfe, 0x00, 0x0c,
	0x00, 0x00, 0x01, 0x00, 0x09, 0xef, 0x7e, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0xab, 0x00, 0x00, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0xcc, 0xef, 0xfe, 0x00, 0x0c,
	0x00, 0x00, 0x00, 0x0c, 0xdd, 0x10, 0x02, 0x00, 0x0c,
	0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x0c,
	0x10, 0x01, 0x00, 0x06, 0x99, 0xf0, 0x1f, 0x00, 0x06,
	0x10, 0x00, 0x00, 0x0a, 0xcc, 0xf0, 0x00, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0c, 0xf0, 0x08, 0x41, 0x00, 0x0d,
	0x08, 0x02, 0x00, 0x06, 0x99, 0xf8, 0x1e, 0x00, 0x06,
	0x00, 0x02, 0x00, 0x0a, 0xcc, 0xff, 0xfe, 0x00, 0x0a,
	0x00, 0x00, 0x00, 0x0d, 0x12, 0x08, 0x41, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x0d,
	0xef, 0xff, 0x00, 0x06, 0xee, 0x0f, 0xe1, 0x00, 0x06,
	0xf0, 0x00, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0d, 0x45, 0xf7, 0xbf, 0x00, 0x0d,
	0xf7, 0xfe, 0x00, 0x06, 0xee, 0x07, 0xe2, 0x00, 0x06,
	0xff, 0xfe, 0x00, 0x0b, 0x00, 0x00, 0x02, 0x00, 0x0b,
	0x00, 0x00, 0x00, 0x0d, 0x67, 0xf7, 0xbf, 0x00, 0x0d,
	0x00, 0x00, 0x00, 0x0d, 0x89, 0x00, 0x00, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x09, 0x01,
	0x00, 0x00, 0x10, 0x0d, 0xaa, 0x00, 0x00, 0x18, 0x0d,
	0x00, 0x00, 0x00, 0x0d, 0xbb, 0x10, 0x82, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00,
	0x08, 0x41, 0x00, 0x09, 0x44, 0x08, 0x61, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x04, 0x00, 0x0d,
	0x00, 0x00, 0x00, 0x0a, 0xcd, 0xdf, 0xfc, 0x00, 0x0d,
	0x00, 0x00, 0x00, 0x0d, 0xee, 0xef, 0x7e, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xe0, 0x01, 0x00,
	0xf7, 0xbf, 0x00, 0x09, 0x77, 0xf7, 0x9f, 0x00, 0x09,
	0x00, 0x00, 0x00, 0x0b, 0x0f, 0xdf, 0xfc, 0x00, 0x0d,
	0x00, 0x00, 0x00, 0x0b, 0x00, 0x20, 0x04, 0x00, 0x0e,
	0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0x23, 0x00, 0x00, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0x44, 0x08, 0x41, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0x56, 0x00, 0x00, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0x77, 0x08, 0x41, 0x00, 0x0e,
	0x00, 0x00, 0x01, 0x00, 0x08, 0xf7, 0xbf, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0x9a, 0x00, 0x00, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0xbb, 0xf7, 0xbf, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0xcd, 0x00, 0x00, 0x00, 0x0e,
	0x00, 0x00, 0x00, 0x0e, 0xee, 0xf7, 0xbf, 0x00, 0x0e,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x09, 0x01,
	0x00, 0x00, 0x10, 0x0e, 0xff, 0x00, 0x00, 0x18, 0x0e,
	0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x0f,
	0x00, 0x00, 0x01, 0x00, 0x02, 0x21, 0x04, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0a, 0xc3, 0x00, 0x00, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x00, 0x0f,
	0x00, 0x00, 0x01, 0x00, 0x05, 0xde, 0xfc, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0b, 0x07, 0x00, 0x00, 0x00, 0x0f,
	0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x0f,
	0x08, 0x00, 0x00, 0x0f, 0x9a, 0x0f, 0xff, 0x00, 0x0f,
	0xf8, 0x00, 0x00, 0x0f, 0xbc, 0xf0, 0x01, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0c, 0xfd, 0x10, 0x82, 0x00, 0x0f,
	0x00, 0x01, 0x00, 0x0f, 0xec, 0xf8, 0x02, 0x00, 0x0f,
	0xff, 0xff, 0x00, 0x0f, 0xfa, 0x07, 0xfe, 0x00, 0x0f,
	0x00, 0x00, 0x00, 0x0d, 0x10, 0x10, 0x82, 0x00, 0x10,
	0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x10,
	0xf8, 0x00, 0x00, 0x0f, 0xb2, 0xf0, 0x01, 0x00, 0x10,
	0x08, 0x00, 0x00, 0x0f, 0x93, 0x0f, 0xff, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x0d, 0x44, 0xef, 0x7e, 0x00, 0x10,
	0xff, 0xff, 0x00, 0x0f, 0xf3, 0x07, 0xfe, 0x00, 0x10,
	0x00, 0x01, 0x00, 0x0f, 0xe2, 0xf8, 0x02, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x0d, 0x65, 0xef, 0x7e, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x10, 0x67, 0x00, 0x00, 0x00, 0x10,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x11, 0x01,
	0x00, 0x00, 0x20, 0x10, 0x88, 0x00, 0x00, 0x30, 0x10,
	0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10,
	0x20, 0x04, 0x00, 0x0a, 0xcc, 0x40, 0x08, 0x00, 0x0a,
	0xdf, 0xfc, 0x00, 0x0a, 0xcc, 0xbf, 0xf8, 0x00, 0x0a,
	0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10,
	0xdf, 0xfc, 0x00, 0x0b, 0x00, 0xbf, 0xf8, 0x00, 0x0b,
	0x20, 0x04, 0x00, 0x0b, 0x00, 0x40, 0x08, 0x00, 0x0b,
	0x00, 0x00, 0x01, 0x00, 0x0b, 0x08, 0x41, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x10, 0xcc, 0x08, 0x01, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x10, 0xdd, 0x08, 0x00, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x10, 0xee, 0xf7, 0xff, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x10, 0xff, 0x00, 0x01, 0x00, 0x10,
	0x00, 0x00, 0x00, 0x11, 0x00, 0x10, 0x82, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x11, 0x08, 0x01, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x22, 0xf7, 0xff, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x33, 0x10, 0x82, 0x00, 0x11,
	0x00, 0x00, 0x01, 0x00, 0x04, 0xf7, 0xbf, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x55, 0xf8, 0x00, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x66, 0xff, 0xff, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x77, 0xef, 0x7e, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0x88, 0xef, 0x7e, 0x00, 0x11,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x11, 0x01,
	0x00, 0x00, 0x20, 0x11, 0x99, 0x00, 0x00, 0x30, 0x11,
	0x00, 0x00, 0x00, 0x11, 0xab, 0x00, 0x00, 0x00, 0x11,
	0x21, 0x04, 0x01, 0x00, 0x00, 0x42, 0x08, 0x01, 0x00,
	0xde, 0xfc, 0x01, 0x00, 0x00, 0xbd, 0xf8, 0x01, 0x00,
	0x00, 0x00, 0x01, 0x00, 0x0c, 0x08, 0x41, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0xde, 0x10, 0x02, 0x00, 0x11,
	0x00, 0x00, 0x00, 0x11, 0xf0, 0x10, 0x00, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x12, 0x12, 0xef, 0xfe, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x02, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x0c, 0xf4, 0x21, 0x04, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x12, 0x56, 0x10, 0x02, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x11, 0xf7, 0xef, 0xfe, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x0d, 0x18, 0x21, 0x04, 0x00, 0x12,
	0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x12, 0x5a, 0xf0, 0x00, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x11, 0xdb, 0xff, 0xfe, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x0d, 0x4c, 0xde, 0xfc, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x0d, 0x6d, 0xde, 0xfc, 0x00, 0x12,
	0x00, 0x00, 0x00, 0x12, 0xef, 0x00, 0x00, 0x00, 0x12,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x21, 0x01,
	0x00, 0x00, 0x40, 0x13, 0x00, 0x00, 0x00, 0x60, 0x13,
	0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x22, 0x08, 0x00, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x33, 0x10, 0x02, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x44, 0xff, 0xff, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x55, 0x10, 0x00, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x66, 0xf8, 0x00, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x77, 0xef, 0xfe, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x88, 0x00, 0x02, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0x99, 0x21, 0x04, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0xaa, 0x00, 0x01, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0xbb, 0x10, 0x02, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0xcc, 0xef, 0xfe, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0xdd, 0x21, 0x04, 0x00, 0x13,
	0x00, 0x00, 0x01, 0x00, 0x0e, 0xf7, 0xbf, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x13, 0xff, 0xf0, 0x00, 0x00, 0x13,
	0x00, 0x00, 0x00, 0x14, 0x00, 0xff, 0xfe, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x14, 0x11, 0xde, 0xfc, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x14, 0x22, 0xde, 0xfc, 0x00, 0x14,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x21, 0x01,
	0x00, 0x00, 0x40, 0x14, 0x33, 0x00, 0x00, 0x60, 0x14,
	0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x41, 0x01,
	0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x14,
	0x00, 0x00, 0x01, 0x00, 0x05, 0x10, 0x00, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x11, 0xd6, 0x20, 0x04, 0x00, 0x14,
	0x00, 0x00, 0x01, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x11, 0xf8, 0x20, 0x00, 0x00, 0x14,
	0x00, 0x00, 0x01, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x12, 0x1a, 0xdf, 0xfc, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x12, 0x1b, 0x00, 0x04, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x0c, 0xfc, 0x42, 0x08, 0x00, 0x14,
	0x00, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x12, 0x5e, 0x20, 0x04, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x11, 0xff, 0xdf, 0xfc, 0x00, 0x14,
	0x00, 0x00, 0x00, 0x0d, 0x10, 0x42, 0x08, 0x00, 0x15,
	0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x12, 0x52, 0xe0, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x11, 0xd3, 0xff, 0xfc, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x0d, 0x44, 0xbd, 0xf8, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x0d, 0x65, 0xbd, 0xf8, 0x00, 0x15,
	0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x41, 0x01,
	0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x15, 0x77, 0x10, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x11, 0xd8, 0x00, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x15, 0x99, 0xff, 0xfe, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x11, 0xfa, 0x00, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x15, 0xbb, 0xf0, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x12, 0x1d, 0x00, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x15, 0xff, 0x00, 0x02, 0x00, 0x15,
	0x00, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x11, 0xf1, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x12, 0x54, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x11, 0xd5, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x0d, 0x46, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x00, 0x0d, 0x67, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x16,
	0x00, 0x00, 0x01, 0x00, 0x09, 0x20, 0x00, 0x00, 0x16,
	0x20, 0x04, 0x00, 0x11, 0xdd, 0x40, 0x08, 0x00, 0x11,
	0x00, 0x00, 0x01, 0x00, 0x0a, 0xff, 0xfc, 0x00, 0x16,
	0x20, 0x00, 0x00, 0x11, 0xff, 0x40, 0x00, 0x00, 0x11,
	0x00, 0x00, 0x01, 0x00, 0x0b, 0xe0, 0x00, 0x00, 0x16,
	0xdf, 0xfc, 0x00, 0x12, 0x11, 0xbf, 0xf8, 0x00, 0x12,
	0x00, 0x04, 0x00, 0x12, 0x11, 0x00, 0x08, 0x00, 0x12,
	0x42, 0x08, 0x00, 0x0c, 0xff, 0x83, 0xf0, 0x00, 0x0c,
	0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x16,
	0x20, 0x04, 0x00, 0x12, 0x55, 0x40, 0x08, 0x00, 0x12,
	0xdf, 0xfc, 0x00, 0x11, 0xff, 0xbf, 0xf8, 0x00, 0x11,
	0x42, 0x08, 0x00, 0x0d, 0x11, 0x83, 0xf1, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x00, 0x0d, 0xf7, 0xbf, 0x00, 0x16,
	0xe0, 0x00, 0x00, 0x12, 0x55, 0xc0, 0x00, 0x00, 0x12,
	0xff, 0xfc, 0x00, 0x11, 0xdd, 0xff, 0xf8, 0x00, 0x11,
	0xbd, 0xf8, 0x00, 0x0d, 0x44, 0x7b, 0xf0, 0x00, 0x0d,
	0xbd, 0xf8, 0x00, 0x0d, 0x66, 0x74, 0x0f, 0x00, 0x0d,
	0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x16,
	0x00, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16,
	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x17,
	0x20, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00,
	0xff, 0xfc, 0x01, 0x00, 0x00, 0xff, 0xf8, 0x01, 0x00,
	0xe0, 0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x00,
	0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
	0x00, 0x00, 0x01, 0x00, 0x05, 0xf7, 0xbf, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x17,
	0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x41, 0x01, 0x00,
	0x00, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xbf, 0x01, 0x00,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
	0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f
};

void dl_init( usb_dev_handle* handle ) {

	uint8_t edid[128];
	uint8_t peek;

	dl_cmdstream cs;
	create( &cs, 10*1024 );

	printf("dl_init(): starting DisplayLink initialization..\n");

	// windows driver does this about once a second:
	// f0005000 seems to be default response
	// f0002000 sometimes seen when device is messed up
	int poll = dl_poll( handle );
	printf( "  dl_poll() = 0x%08x\n", poll );

	/*for (int base = 0; base < 0x100; base++) {
		printf("  register space @ 0x%04x:\n", base<<8 );
		for (int i = 0; i < 256; i++ ) {
			if (i % 16 == 0) printf("    ");
			peek = dl_peek( (base<<8)+i, handle );
			printf("%02hhx ",peek);
			if (i % 16 == 15) printf("\n");
		}
	} exit(1);*/

	// always seems to return 0x82
	peek = dl_peek( 0xC484, handle );
	printf( "  dl_peek(0xC484) = 0x%02hhx\n", peek );

	// original driver does this, but no visible effect
	printf( "  dl_poke(0xC41F,0x01)\n" );
	dl_poke( 0xC41F, 0x01, handle );

	dl_get_edid( edid, handle );
	printf( "  EDID data:\n" );
	for (int i = 0; i < 8; i++) {
		printf( "    " );
		for (int j = 0; j < 16; j++) printf( "%02hhx ", edid[i*16+j] );
		printf( "\n" );
	}

	printf( "  setting decryption null-key..\n" );
	dl_set_key( nullkey1, handle );

	// original driver does this, but no visible effect
	printf( "  dl_poke(0xC40B,0x00)\n" );
	dl_poke( 0xC40B, 0x00, handle );
	
	printf( "  sending decompressor table (%d bytes)..\n", sizeof(dl_decomp_table) );
	dl_decomp_table_command( &cs, sizeof(dl_decomp_table), dl_decomp_table );
	send( &cs, handle );

	printf("dl_init(): initialization done.\n\n");
	destroy( &cs );
}


/******************* HELPER FUNCTIONS *********************/

usb_dev_handle* usb_get_device_handle( int vendor, int product, int interface = 0 ) {

	usb_init();
	usb_find_busses();
	usb_find_devices();

	struct usb_bus* busses = usb_get_busses();
		
	for ( struct usb_bus* bus = busses; bus; bus = bus->next ) {
		for ( struct usb_device* dev = bus->devices; dev; dev = dev->next ) {
			if ((dev->descriptor.idVendor == vendor) && (dev->descriptor.idProduct == product)) {
				usb_dev_handle* handle = usb_open(dev);
				if (!handle) return 0;
				if (usb_claim_interface(handle,0) < 0) return 0;
				return handle;
			}
		}
	}
	return 0;
}

void rgb24_to_rgb16( uint8_t* rgb24, uint8_t* rgb16, int count ) {
	for (int i = 0; i < count; i++) {
		uint8_t r = rgb24[i*3+0];
		uint8_t g = rgb24[i*3+1];
		uint8_t b = rgb24[i*3+2];
		rgb16[i*2+0] =  (r & 0xF1)       | ((g & 0xE0) >> 5);
		rgb16[i*2+1] = ((g & 0x1C) << 3) | ((b & 0xF1) >> 3);
	}
}


void read_rgb24( const char* filename, uint8_t* rgb24, int count ) {
	int f = open(filename,O_RDONLY);
	read( f, rgb24, count*3 );
	close(f);
}

uint8_t* read_rgb16( const char* filename, int count ) {

	uint8_t* rgb16 = (uint8_t*)malloc(count*2);
	uint8_t* rgb24 = (uint8_t*)malloc(count*3);

	read_rgb24(filename,rgb24,count);
	rgb24_to_rgb16(rgb24,rgb16,count);

	free( rgb24 );
	return rgb16;
}


/******************* MAIN ROUTINE *************************/

int main(int argc, char* argv[] ) {

	printf("\ndisplaylink userspace controller demo 0.0.1\n\n");
	printf("written 2008/09 by floe at butterbrot.org\n");
	printf("in cooperation with chrisly at platon42.de\n");
 	printf("this code is released as public domain.\n\n");
	printf("this is so experimental that the warranty shot itself.\n");
	printf("so don't expect any.\n\n");
	printf("(note: you can pass a 640x960 pixel RGB raw image file as parameter)\n\n");

	#define XRES 640
	#define YRES 480

	dl_cmdstream cs;
	create( &cs, 1024*1024 );

	usb_dev_handle* handle = usb_get_device_handle( 0x17E9, 0x01AE );
	if (!handle) return 1;

	// startup control messages & firmware
	dl_init( handle );

	// default register set & offsets
	printf("setting default registers for 640x480@xxxxxx\n");
	dl_set_registers( &cs, dl_register_init_640 );
	dl_set_offsets( &cs, 0x000000, 0x000A00, 0x555555, 0x000500 );
	/*dl_set_offsets( &cs, 0x000000, 0x000A00, 0x555555, 0x000500 );
	dl_unknown_command( &cs );
	dl_set_offsets( &cs, 0x000000, 0x000A00, 0x555555, 0x000500 );*/
	dl_set_register( &cs, DL_REG_BLANK_SCREEN, 0x00 ); // enable output
	dl_set_register( &cs, DL_REG_SYNC, 0xFF );
	dl_sync_command( &cs );
	send( &cs, handle );

	sleep(1);

	// fill with a bunch of red
	printf("filling screen with red gradient..\n");
	rle_word red = { 0x00, 0x0000 };
	for (int i = 0; i < YRES; i++) {
		dl_gfx_rle( &cs, i*XRES*2,      0x00, &red );
		dl_gfx_rle( &cs, i*XRES*2+512,  0x00, &red );
		dl_gfx_rle( &cs, i*XRES*2+1024, 0x00, &red );
		red.value = (i/15) << 11;
	}
	dl_sync_command( &cs );
	send( &cs, handle );

	sleep(1);

	// grr. I'm pretty sure that I'm right about the stride register,
	// but I can't get it to have any effect...
	/*dl_set_register( &cs, DL_REG_SYNC, 0x00 );
	dl_set_address(  &cs, DL_ADDR_FB16_STRIDE, X*2 );
	dl_set_address(  &cs, DL_ADDR_FB8_STRIDE, X );
	dl_set_register( &cs, DL_REG_SYNC, 0xFF );
	dl_sync_command( &cs );
	send( &cs, handle );*/

	if (argc >= 2) {

		// fill with an image
		printf("filling screen with an image..\n");
		#define X 640
		#define Y 960

		uint8_t* image = read_rgb16(argv[1],X*Y);
		for (int i = 0; i < (X*Y)/256; i++) {
			dl_gfx_write( &cs, i*256*2, 0x00, image+(i*256*2) );
			if ((i % 100) == 0) {
				dl_sync_command( &cs );
				send( &cs, handle );
			}
		}
		dl_sync_command( &cs );
		send( &cs, handle );

		sleep(1);
	}

	// some vertical scrolling
	printf("doing vertical scrolling (why doesn't horizontal work?)..\n");
	for (int i = 0; i < YRES; i++) {
		dl_set_register( &cs, DL_REG_SYNC, 0x00 );
		dl_set_address(  &cs, DL_ADDR_FB16_START, i*XRES*2 );
		dl_set_register( &cs, DL_REG_SYNC, 0xFF );
		dl_sync_command( &cs );
		send( &cs, handle );
		usleep(5000);
	}

	sleep(1);

	// some memcopy
	printf("doing bitblt..\n\n");
	dl_set_offsets( &cs, 0x000000, 0x000A00, 0x555555, 0x000500 );
	for (int i = 0; i < 100; i++) {
		dl_gfx_copy( &cs, 0x500*(280+i)+320*2, 0x500*(380+i)+420*2, 100 );
	}
	dl_sync_command( &cs );
	send( &cs, handle );

	printf("goodbye.\n\n");
	usb_close( handle );
	destroy( &cs );
}

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux