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