Appendix A: Commented Code

 

            The following is a commented version of our entire code:

//********************************************************************************

:Image Writer_1

#include <stdio.h>

#include <string.h>

#define TV_IMG_WIDTH 48

#define TV_IMG_HEIGHT 36

 

int convbmp(char *infilename, char *outfilename) {

      FILE *infile, *outfile;

      unsigned int n, i, j, k;

 

      int tmp;

      unsigned int imgoffset = 0, hdrsize=0, pixelbit = 0, compr = 0, imgwidth = 0, imgheight = 0;

      int scaleheight, scalewidth;

      unsigned char pixbuf[3];

      char flashstr[32];

      char buf[3];

      unsigned char color;

 

      // open input file

      if( (infile = fopen(infilename, "rb")) == NULL ) {

            printf("Open error\n");

            return -1;

      }

 

      // be careful big-endian: 3-4-1-2

      // read magic ident

      if( fseek(infile, 10, SEEK_SET) == -1 ) {

            printf("fseek error\n");

            return -1;

      }

      // read offset of image

      fread( &tmp, sizeof(char), 2, infile);

      imgoffset = tmp;

      fread( &tmp, sizeof(char), 2, infile);

      imgoffset += (tmp << 16);

 

      /*

      fread( &tmp, sizeof(char), 4, infile);

      printf("%d\n", tmp);

      */

      // skip

      if( fseek(infile, 4, SEEK_CUR) == -1 ) {

            printf("fseek error\n");

            return -1;

      }

      // read img width

      fread( &tmp, sizeof(char), 2, infile);

      imgwidth = tmp;

      fread( &tmp, sizeof(char), 2, infile);

      imgwidth += (tmp << 16);

      printf("%d\n", imgwidth);

      scalewidth = imgwidth / TV_IMG_WIDTH;

      // read img height

      fread( &tmp, sizeof(char), 2, infile);

      imgheight = tmp;

      fread( &tmp, sizeof(char), 2, infile);

      imgheight += (tmp << 16);

      printf("%d\n", imgheight);

      scaleheight = imgheight / TV_IMG_HEIGHT;

 

      // skip irrelevant

      if( fseek(infile, 2, SEEK_CUR) == -1 ) {

            printf("fseek error\n");

            return -1;

      }

      // read number of bit for a pixel

      fread( &tmp, sizeof(char), 2, infile);

      pixelbit = tmp;

      printf("%d\n", pixelbit);

      if(pixelbit != 24) {

            printf("not supported yet\n");

            return -1;

      }

 

      // read compressed

      fread( &tmp, sizeof(char), 2, infile);

      compr = tmp;

      fread( &tmp, sizeof(char), 2, infile);

      compr += (tmp << 16);

      printf("%d\n", compr);

      if(compr != 0) {

            printf("compressed, not supported yet\n");

            return -1;

      }

 

      // reset

      if( fseek(infile, imgoffset, SEEK_SET) == -1 ) {

            printf("fseek error\n");

            return -1;

      }

      printf("%d\n", imgoffset);

 

      // write out

      // open output

      if( (outfile = fopen(outfilename, "w+")) == NULL ) {

            printf("Open error\n");

            return -1;

      }

 

      k = 0;

      for( j=TV_IMG_HEIGHT; j>0; j-- ) {

            if( fseek(infile, imgoffset+TV_IMG_WIDTH*3*(j-1), SEEK_SET) == -1 ) {

                  printf("fseek error\n");

                  return -1;

            }

 

            for( i=0; i<TV_IMG_WIDTH; i++ ) {

                  n = fread(pixbuf, sizeof(char), 3, infile);

 

                  color = pixbuf[0] >> 7 << 3; // r, b?

                  //color = color | ( pixbuf[1] >> 6 ); // g

                  color = color | ( pixbuf[1] >> 7 );

                  color = color | ( pixbuf[1] << 1 >> 6 );

                  color = color | ( pixbuf[2] >> 7 << 2 );

 

                  if( k % 2 == 0 ) {

                       sprintf(flashstr, "0x%.1X", color);                 

                  }

                  else {

                        sprintf(flashstr, "%.1X, ", color);     

                  }

                  n = fwrite(flashstr, sizeof(char), 3, outfile);

                  k++;

            }

            sprintf(flashstr, "\n");                

            fwrite(flashstr, sizeof(char), 1, outfile);                          

           

      }

      fclose(outfile);

      fclose(infile);

      return 1;

}

 

int main() {

      char infilename[32];

      char outfilename[32];

      printf("input:");

      scanf("%s", infilename);

      strcpy(outfilename, "output.txt");

      if(convbmp(infilename, outfilename) < 0) {

            printf("error in convbmp\n");

      }

      return 1;

}

 

Image writer2:

// SPI information obtained from SanDisk's SD card manual

// http://www.sandisk.com/pdf/oem/ProdManualSDCardv1.9.pdf

 

/*

    Portions of this code were adapted and used from

    Radig Ulrich <mail@ulrichradig.de>

*/

#include "sdcard.h"

#include "stdio.h"

#define TRUE  (0x1)

#define FALSE (0x0)

 

#define R1_IN_IDLE_STATE    (0x1)   // The card is in idle state and running initializing process.

#define R1_ERASE_RESET      (0x2)   // An erase sequence was cleared before executing because of an out of erase sequence command was received.

#define R1_ILLEGAL_COMMAND  (0x4)   // An illegal command code was detected

#define R1_COM_CRC_ERROR    (0x8)   // The CRC check of the last command failed.

#define R1_ERASE_SEQ_ERROR  (0x10)  // An error in the sequence of erase commands occured.

#define R1_ADDRESS_ERROR    (0x20)  // A misaligned address, which did not match the block length was used in the command.

#define R1_PARAMETER        (0x40)  // The command's argument (e.g. address, block length) was out of the allowed range for this card.

 

#define READ_START_BLOCK            (0b11111110)

#define WRITE_SINGLE_START_BLOCK    (0b11111110)

#define WRITE_MULTIPLE_START_BLOCK  (0b11111100)

#define WRITE_MULTIPLE_STOP_TRAN    (0b11111101)

#define MMC_DR_MASK                 0x1F

#define MMC_DR_ACCEPT               0x05

 

#define MSTR                4

#define SPR0                0

#define SPR1                1

#define SPE                 6

#define SPI2X               0

#define SPIF                7

 

#define MMC_Write           PORTB

#define MMC_Read            PINB

#define MMC_Direction_REG   DDRB

 

#define SPI_DI              6

#define SPI_DO              5

#define SPI_Clock           7

#define MMC_Chip_Select     0

#define SPI_SS              4

 

#define nop()               #asm("nop")

 

//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)

#define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);

 

//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)

#define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select);

 

unsigned char screen[512];

 

flash unsigned char img[5238]={

0x42, 0x4D, 0x76, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,

0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,

0x00, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xB7, 0x76, 0xD6, 0xBD, 0x75, 0xDC, 0xC2, 0x75, 0xDC,

0xBF, 0x6E, 0xDA, 0xBA, 0x67, 0xD8, 0xB4, 0x60, 0xD4, 0xAD, 0x58, 0xCC, 0xA1, 0x4A, 0xC2, 0x93,

0x3F, 0xBA, 0x88, 0x36, 0xB1, 0x7D, 0x31, 0x97, 0x60, 0x1B, 0x8E, 0x58, 0x1B, 0x8B, 0x55, 0x20,

0x74, 0x3F, 0x14, 0x65, 0x31, 0x0D, 0x5C, 0x28, 0x0A, 0x3F, 0x14, 0x01, 0x27, 0x09, 0x04, 0x4E,

0x3E, 0x45, 0x3E, 0x3A, 0x46, 0x26, 0x2D, 0x41, 0x09, 0x14, 0x34, 0x08, 0x18, 0x43, 0x0F, 0x24,

0x57, 0x05, 0x21, 0x57, 0x00, 0x0F, 0x45, 0x03, 0x24, 0x56, 0x19, 0x2D, 0x5C, 0x4A, 0x51, 0x78,

0x48, 0x3E, 0x5C, 0x1E, 0x0A, 0x21, 0x25, 0x12, 0x21, 0x8E, 0x73, 0x83, 0xBC, 0x93, 0xAF, 0x9E,

0x77, 0x97, 0xB1, 0x9B, 0xB7, 0xDD, 0xC7, 0xE0, 0xEE, 0xC1, 0xDB, 0xFE, 0xCC, 0xE4, 0x71, 0x43,

0x59, 0x17, 0x05, 0x16, 0x43, 0x65, 0x72, 0x38, 0x72, 0x7E, 0x1A, 0x53, 0x68, 0x00, 0x13, 0x34,

0x00, 0x03, 0x34, 0x11, 0x16, 0x53, 0xD4, 0xB7, 0x72, 0xD8, 0xBB, 0x71, 0xDF, 0xC1, 0x72, 0xE1,

0xC0, 0x70, 0xE1, 0xBF, 0x6B, 0xDF, 0xBA, 0x65, 0xD9, 0xB1, 0x58, 0xCD, 0xA3, 0x4A, 0xC4, 0x95,

0x3F, 0xBC, 0x8D, 0x39, 0xB0, 0x7F, 0x31, 0xA3, 0x6F, 0x29, 0x98, 0x62, 0x25, 0x86, 0x51, 0x1E,

0x70, 0x3C, 0x13, 0x67, 0x34, 0x14, 0x65, 0x32, 0x18, 0x51, 0x28, 0x19, 0x2E, 0x1D, 0x1A, 0x2F,

0x28, 0x2F, 0x14, 0x09, 0x19, 0x3E, 0x38, 0x4F, 0x18, 0x1F, 0x40, 0x00, 0x09, 0x2F, 0x00, 0x0C,

0x39, 0x00, 0x19, 0x4A, 0x00, 0x19, 0x4C, 0x07, 0x1E, 0x50, 0x1B, 0x30, 0x5D, 0x43, 0x54, 0x7B,

0x51, 0x5E, 0x7E, 0x54, 0x58, 0x71, 0x30, 0x23, 0x39, 0x21, 0x01, 0x14, 0xA3, 0x6B, 0x80, 0xB9,

0x86, 0x9A, 0xCE, 0xB9, 0xCF, 0xD4, 0xC6, 0xDE, 0xDE, 0xBC, 0xDB, 0xE6, 0xBC, 0xDF, 0x71, 0x48,

0x68, 0x27, 0x16, 0x31, 0x51, 0x71, 0x84, 0x46, 0x7A, 0x8A, 0x2D, 0x5E, 0x74, 0x00, 0x18, 0x3B,

0x01, 0x07, 0x3C, 0x18, 0x1C, 0x5D, 0xD7, 0xB7, 0x6E, 0xDA, 0xBB, 0x70, 0xE1, 0xC0, 0x71, 0xE4,

0xC1, 0x71, 0xE6, 0xC1, 0x6F, 0xE1, 0xBC, 0x67, 0xDA, 0xB2, 0x5A, 0xCD, 0xA2, 0x4B, 0xC3, 0x95,

0x41, 0xBD, 0x8E, 0x3D, 0xAC, 0x7D, 0x33, 0xA7, 0x75, 0x33, 0x95, 0x64, 0x2C, 0x84, 0x51, 0x26,

0x7D, 0x4A, 0x29, 0x78, 0x46, 0x2F, 0x64, 0x33, 0x23, 0x3C, 0x1B, 0x12, 0x37, 0x30, 0x33, 0x22,

0x24, 0x2F, 0x31, 0x25, 0x37, 0x28, 0x1D, 0x37, 0x17, 0x1B, 0x38, 0x06, 0x17, 0x38, 0x00, 0x0E,

0x33, 0x00, 0x14, 0x3D, 0x02, 0x17, 0x44, 0x12, 0x22, 0x50, 0x20, 0x34, 0x5D, 0x29, 0x41, 0x65,

0x46, 0x62, 0x81, 0x64, 0x76, 0x93, 0x55, 0x51, 0x6E, 0x45, 0x28, 0x3F, 0x42, 0x04, 0x12, 0xAE,

0x71, 0x7B, 0xF9, 0xE1, 0xEB, 0xEA, 0xDD, 0xEB, 0xEC, 0xCF, 0xE6, 0xDE, 0xB5, 0xD4, 0x77, 0x4C,

0x6D, 0x2C, 0x17, 0x37, 0x5D, 0x76, 0x90, 0x50, 0x7D, 0x98, 0x3D, 0x62, 0x84, 0x04, 0x1B, 0x48,

0x08, 0x09, 0x43, 0x18, 0x1E, 0x5F, 0xDB, 0xBB, 0x6F, 0xDD, 0xBD, 0x71, 0xE0, 0xBC, 0x70, 0xE7,

0xC0, 0x75, 0xE7, 0xC1, 0x73, 0xDF, 0xB8, 0x69, 0xD6, 0xAE, 0x5C, 0xCD, 0xA2, 0x53, 0xC1, 0x95,

0x48, 0xB5, 0x89, 0x42, 0xA9, 0x7D, 0x3D, 0xA0, 0x72, 0x3C, 0x89, 0x5C, 0x30, 0x77, 0x4A, 0x29,

0x6F, 0x42, 0x2D, 0x62, 0x35, 0x2A, 0x58, 0x2D, 0x2A, 0x4F, 0x34, 0x38, 0x1E, 0x22, 0x2D, 0x28,

0x32, 0x44, 0x3B, 0x33, 0x4A, 0x36, 0x2B, 0x45, 0x22, 0x21, 0x3B, 0x08, 0x12, 0x2A, 0x00, 0x0B,

0x24, 0x00, 0x12, 0x2D, 0x00, 0x0B, 0x28, 0x09, 0x16, 0x36, 0x1B, 0x30, 0x50, 0x3B, 0x57, 0x79,

0x57, 0x7A, 0x9B, 0x4A, 0x66, 0x88, 0x49, 0x51, 0x76, 0x8C, 0x74, 0x92, 0x7C, 0x3D, 0x47, 0x3B,

0x00, 0x00, 0x79, 0x5F, 0x58, 0xFD, 0xF0, 0xE8, 0xF0, 0xD0, 0xD1, 0xE0, 0xB5, 0xC0, 0xA1, 0x72,

0x88, 0x2C, 0x10, 0x2E, 0x6C, 0x79, 0x9F, 0x63, 0x84, 0xB1, 0x4B, 0x65, 0x9B, 0x0A, 0x1A, 0x55,

0x16, 0x12, 0x53, 0x0D, 0x15, 0x51, 0xD6, 0xB7, 0x68, 0xD9, 0xB8, 0x69, 0xE1, 0xBA, 0x6F, 0xE4,

0xBD, 0x73, 0xE5, 0xBD, 0x72, 0xDF, 0xB7, 0x6C, 0xD7, 0xAE, 0x65, 0xCE, 0xA4, 0x5F, 0xC1, 0x97,

0x56, 0xB5, 0x8B, 0x50, 0x96, 0x6E, 0x3A, 0x8E, 0x66, 0x3C, 0x7B, 0x55, 0x37, 0x6F, 0x4A, 0x36,

0x64, 0x40, 0x38, 0x4F, 0x2D, 0x2E, 0x40, 0x1E, 0x25, 0x36, 0x23, 0x32, 0x19, 0x22, 0x36, 0x25,

0x37, 0x4E, 0x2F, 0x30, 0x4A, 0x19, 0x15, 0x2E, 0x06, 0x03, 0x19, 0x00, 0x00, 0x10, 0x00, 0x00,

0x10, 0x00, 0x06, 0x1A, 0x00, 0x0C, 0x22, 0x04, 0x16, 0x2D, 0x0F, 0x28, 0x42, 0x22, 0x41, 0x60,

0x36, 0x59, 0x7B, 0x36, 0x56, 0x7A, 0x40, 0x51, 0x7C, 0x77, 0x6A, 0x8A, 0xA8, 0x6E, 0x73, 0xA0,

0x5F, 0x50, 0x50, 0x32, 0x15, 0x60, 0x4A, 0x27, 0xEC, 0xC3, 0xA2, 0xFF, 0xD0, 0xBB, 0x99, 0x60,

0x5E, 0x37, 0x11, 0x23, 0x6A, 0x6D, 0x93, 0x60, 0x78, 0xAE, 0x4D, 0x62, 0xA6, 0x2B, 0x37, 0x7F,

0x2E, 0x2C, 0x6E, 0x1A, 0x24, 0x5A, 0xD8, 0xB7, 0x68, 0xD7, 0xB6, 0x67, 0xDA, 0xB3, 0x68, 0xDD,

0xB4, 0x6B, 0xDB, 0xB3, 0x6B, 0xD7, 0xAE, 0x69, 0xD1, 0xA9, 0x68, 0xCA, 0xA2, 0x67, 0xBB, 0x94,

0x60, 0xAB, 0x86, 0x5A, 0x9F, 0x7D, 0x59, 0x8F, 0x70, 0x57, 0x78, 0x5B, 0x4D, 0x69, 0x4E, 0x4A,

0x5A, 0x43, 0x48, 0x3F, 0x2B, 0x38, 0x31, 0x1D, 0x30, 0x30, 0x25, 0x3F, 0x2A, 0x35, 0x51, 0x25,

0x3A, 0x56, 0x13, 0x24, 0x3F, 0x00, 0x06, 0x1E, 0x03, 0x00, 0x16, 0x0C, 0x00, 0x16, 0x06, 0x00,

0x0F, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0x00, 0x0C, 0x22, 0x01, 0x23, 0x40,

0x22, 0x3D, 0x62, 0x3F, 0x58, 0x82, 0x49, 0x63, 0x91, 0x5A, 0x5D, 0x7C, 0x96, 0x68, 0x67, 0x8F,

0x53, 0x35, 0x98, 0x72, 0x3C, 0x87, 0x63, 0x1D, 0xA8, 0x70, 0x23, 0xE9, 0xA8, 0x64, 0xF3, 0xAE,

0x86, 0x5E, 0x2D, 0x23, 0x61, 0x5A, 0x75, 0x69, 0x78, 0xB0, 0x5A, 0x6C, 0xB9, 0x38, 0x46, 0x98,

0x27, 0x2A, 0x6E, 0x26, 0x30, 0x5F, 0xD8, 0xB7, 0x67, 0xD8, 0xB5, 0x65, 0xDE, 0xB7, 0x69, 0xDE,

0xB5, 0x6C, 0xDB, 0xB3, 0x6B, 0xD6, 0xAE, 0x6D, 0xD4, 0xAC, 0x72, 0xCB, 0xA6, 0x74, 0xB9, 0x96,

0x6E, 0xA6, 0x87, 0x68, 0x9B, 0x7E, 0x69, 0x8C, 0x73, 0x69, 0x78, 0x64, 0x63, 0x6C, 0x5D, 0x65,

0x60, 0x54, 0x66, 0x43, 0x3B, 0x52, 0x2E, 0x29, 0x46, 0x2D, 0x2F, 0x4E, 0x16, 0x22, 0x44, 0x10,

0x25, 0x45, 0x01, 0x19, 0x37, 0x00, 0x0E, 0x29, 0x12, 0x0E, 0x2B, 0x20, 0x11, 0x2D, 0x22, 0x13,

0x2E, 0x21, 0x1E, 0x37, 0x13, 0x2E, 0x43, 0x00, 0x1F, 0x34, 0x00, 0x12, 0x2A, 0x00, 0x18, 0x38,

0x13, 0x2C, 0x54, 0x44, 0x5B, 0x88, 0x51, 0x6F, 0x9E, 0x3E, 0x47, 0x62, 0x5D, 0x36, 0x28, 0x82,

0x49, 0x16, 0xC7, 0x9A, 0x49, 0xD9, 0xA9, 0x43, 0xC5, 0x84, 0x11, 0xEA, 0xA1, 0x35, 0xFF, 0xC3,

0x73, 0x99, 0x62, 0x37, 0x44, 0x34, 0x35, 0x71, 0x77, 0x9C, 0x6C, 0x7A, 0xBC, 0x42, 0x50, 0x98,

0x20, 0x28, 0x64, 0x3D, 0x49, 0x71, 0xD6, 0xB3, 0x63, 0xD4, 0xB2, 0x5F, 0xD5, 0xAE, 0x5F, 0xD5,

0xAE, 0x60, 0xD1, 0xA9, 0x61, 0xCA, 0xA4, 0x64, 0xC6, 0xA0, 0x6A, 0xBB, 0x99, 0x6E, 0xA8, 0x8B,

0x6C, 0x94, 0x7B, 0x67, 0x79, 0x64, 0x5C, 0x70, 0x62, 0x64, 0x64, 0x5C, 0x67, 0x60, 0x5E, 0x72,

0x5B, 0x5F, 0x78, 0x42, 0x4A, 0x68, 0x27, 0x31, 0x53, 0x1E, 0x2C, 0x50, 0x22, 0x33, 0x54, 0x1B,

0x30, 0x50, 0x0C, 0x25, 0x45, 0x07, 0x18, 0x39, 0x0C, 0x0C, 0x30, 0x17, 0x0E, 0x36, 0x4A, 0x41,

0x69, 0x7F, 0x87, 0xAC, 0x66, 0x8B, 0xAD, 0x3D, 0x72, 0x93, 0x12, 0x48, 0x69, 0x02, 0x2F, 0x54,

0x09, 0x25, 0x4E, 0x31, 0x49, 0x73, 0x49, 0x65, 0x8E, 0x2C, 0x34, 0x45, 0x44, 0x20, 0x00, 0x9F,

0x67, 0x1A, 0xCE, 0x97, 0x2E, 0xF8, 0xBE, 0x3D, 0xF2, 0xA9, 0x19, 0xF2, 0xA5, 0x19, 0xF1, 0xA9,

0x33, 0xCB, 0x94, 0x3F, 0x47, 0x2E, 0x06, 0x6B, 0x67, 0x66, 0x6B, 0x73, 0x91, 0x50, 0x5D, 0x8B,

0x36, 0x41, 0x6D, 0x57, 0x68, 0x89, 0xD8, 0xB5, 0x65, 0xD5, 0xB3, 0x60, 0xD2, 0xAD, 0x59, 0xD3,

0xAC, 0x5D, 0xCE, 0xA8, 0x60, 0xC6, 0xA1, 0x63, 0xBE, 0x9B, 0x69, 0xB3, 0x94, 0x6D, 0xA0, 0x86,

0x6E, 0x8D, 0x79, 0x6E, 0x7D, 0x6F, 0x71, 0x6C, 0x66, 0x71, 0x4F, 0x50, 0x64, 0x3A, 0x43, 0x5E,

0x38, 0x47, 0x68, 0x2F, 0x42, 0x67, 0x18, 0x32, 0x57, 0x10, 0x2A, 0x4E, 0x13, 0x2B, 0x49, 0x0D,

0x22, 0x41, 0x0D, 0x20, 0x41, 0x1C, 0x29, 0x4F, 0x20, 0x20, 0x4E, 0x0B, 0x0A, 0x3C, 0x16, 0x1D,

0x4F, 0x3B, 0x50, 0x83, 0x50, 0x7B, 0xAC, 0x45, 0x7D, 0xAC, 0x2A, 0x65, 0x92, 0x1E, 0x54, 0x7D,

0x11, 0x37, 0x61, 0x24, 0x41, 0x68, 0x42, 0x59, 0x7F, 0x2F, 0x30, 0x34, 0x52, 0x2D, 0x00, 0xB8,

0x7E, 0x15, 0xE1, 0xA4, 0x26, 0xFF, 0xCE, 0x3D, 0xF3, 0xA9, 0x09, 0xF0, 0xA6, 0x06, 0xFA, 0xB7,

0x26, 0xE7, 0xB2, 0x3A, 0x95, 0x75, 0x22, 0x80, 0x71, 0x43, 0x68, 0x68, 0x5C, 0x55, 0x5E, 0x6B,

0x47, 0x54, 0x6E, 0x55, 0x67, 0x86, 0xD7, 0xB6, 0x66, 0xD7, 0xB5, 0x61, 0xDC, 0xB8, 0x60, 0xDF,

0xBB, 0x67, 0xDB, 0xB9, 0x6D, 0xD3, 0xB0, 0x70, 0xC8, 0xA8, 0x77, 0xBB, 0xA1, 0x7D, 0xAB, 0x96,

0x81, 0x9A, 0x8A, 0x84, 0x8B, 0x83, 0x8A, 0x75, 0x75, 0x87, 0x45, 0x4E, 0x69, 0x1F, 0x30, 0x51,

0x1E, 0x36, 0x5A, 0x22, 0x41, 0x68, 0x12, 0x36, 0x5E, 0x05, 0x29, 0x4D, 0x0C, 0x2D, 0x47, 0x0E,

0x25, 0x3F, 0x28, 0x31, 0x53, 0x5D, 0x5E, 0x8A, 0x75, 0x79, 0xAE, 0x4F, 0x5D, 0x98, 0x1C, 0x38,

0x78, 0x0B, 0x33, 0x74, 0x21, 0x51, 0x93, 0x30, 0x67, 0xA4, 0x21, 0x61, 0x97, 0x2A, 0x68, 0x98,

0x1E, 0x54, 0x7D, 0x1F, 0x47, 0x6A, 0x41, 0x50, 0x71, 0x35, 0x2A, 0x22, 0x83, 0x56, 0x00, 0xE9,

0xA9, 0x25, 0xE2, 0x9E, 0x0F, 0xFB, 0xB5, 0x1B, 0xFF, 0xDC, 0x37, 0xFF, 0xC8, 0x20, 0xF9, 0xC0,

0x1D, 0xF6, 0xC6, 0x32, 0xE5, 0xBF, 0x43, 0xBA, 0xA0, 0x42, 0x9D, 0x92, 0x56, 0x7A, 0x7B, 0x61,

0x5D, 0x69, 0x6D, 0x4F, 0x64, 0x80, 0xD6, 0xB0, 0x62, 0xD5, 0xB0, 0x60, 0xCC, 0xA7, 0x53, 0xD1,

0xAB, 0x59, 0xCE, 0xAB, 0x61, 0xC4, 0xA4, 0x63, 0xB8, 0x9A, 0x69, 0xAB, 0x93, 0x6F, 0x9B, 0x8A,

0x77, 0x8C, 0x81, 0x7D, 0x75, 0x71, 0x7C, 0x68, 0x6C, 0x84, 0x43, 0x50, 0x70, 0x22, 0x38, 0x5C,

0x25, 0x43, 0x6C, 0x2C, 0x4F, 0x7A, 0x11, 0x3B, 0x65, 0x00, 0x21, 0x46, 0x15, 0x39, 0x57, 0x00,

0x18, 0x34, 0x00, 0x00, 0x20, 0x15, 0x17, 0x40, 0x47, 0x4E, 0x7F, 0x60, 0x73, 0xAC, 0x67, 0x8A,

0xC9, 0x75, 0xA2, 0xE5, 0x46, 0x78, 0xC0, 0x46, 0x7F, 0xC4, 0x24, 0x62, 0xA2, 0x28, 0x68, 0x9F,

0x21, 0x5C, 0x89, 0x1B, 0x45, 0x6A, 0x34, 0x43, 0x63, 0x2C, 0x1D, 0x0D, 0xB1, 0x84, 0x1B, 0xF2,

0xB6, 0x1D, 0xFB, 0xB9, 0x1E, 0xFF, 0xC6, 0x27, 0xFF, 0xD8, 0x36, 0xEF, 0xB4, 0x11, 0xFF, 0xD5,

0x34, 0xFF, 0xD6, 0x3B, 0xF1, 0xC8, 0x36, 0xE9, 0xC9, 0x47, 0xEF, 0xDB, 0x70, 0xC0, 0xB6, 0x68,

0x96, 0x97, 0x6D, 0x7C, 0x80, 0x7A, 0xCB, 0x9C, 0x58, 0xCC, 0x9E, 0x57, 0xD0, 0xA3, 0x59, 0xCE,

0xA3, 0x5A, 0xC8, 0xA1, 0x5C, 0xBF, 0x9E, 0x5F, 0xB4, 0x97, 0x64, 0xA5, 0x90, 0x6A, 0x96, 0x88,

0x72, 0x8B, 0x83, 0x7C, 0x7B, 0x7C, 0x86, 0x6B, 0x72, 0x8B, 0x35, 0x45, 0x69, 0x0B, 0x23, 0x4D,

0x34, 0x55, 0x82, 0x1A, 0x41, 0x6E, 0x00, 0x2C, 0x58, 0x09, 0x34, 0x5F, 0x1C, 0x3F, 0x67, 0x27,

0x3E, 0x64, 0x09, 0x17, 0x3B, 0x06, 0x10, 0x32, 0x00, 0x08, 0x2A, 0x00, 0x12, 0x38, 0x02, 0x20,

0x4F, 0x3D, 0x64, 0x9B, 0x40, 0x72, 0xB4, 0x3F, 0x77, 0xBE, 0x2F, 0x6B, 0xB1, 0x23, 0x5D, 0x9E,

0x3F, 0x71, 0xA5, 0x26, 0x4D, 0x74, 0x0C, 0x22, 0x3E, 0x54, 0x52, 0x3A, 0xB3, 0x90, 0x1B, 0xEF,

0xBF, 0x1A, 0xF9, 0xC6, 0x22, 0xEB, 0xB7, 0x16, 0xFF, 0xE2, 0x48, 0xFF, 0xD5, 0x44, 0xFF, 0xC8,

0x3F, 0xFF, 0xCE, 0x45, 0xFF, 0xD5, 0x42, 0xE9, 0xC4, 0x2C, 0xF9, 0xDD, 0x42, 0xDB, 0xC3, 0x35,

0xD6, 0xBE, 0x4E, 0xC9, 0xAA, 0x5F, 0xC7, 0x92, 0x53, 0xC9, 0x97, 0x55, 0xD0, 0x9D, 0x5E, 0xCF,

0x9E, 0x60, 0xCC, 0xA0, 0x65, 0xC3, 0x9F, 0x69, 0xB7, 0x9A, 0x6E, 0xA8, 0x93, 0x74, 0x99, 0x8C,

0x7C, 0x8C, 0x86, 0x87, 0x7D, 0x7E, 0x92, 0x81, 0x8A, 0xAB, 0x4E, 0x5E, 0x89, 0x0A, 0x21, 0x53,

0x25, 0x44, 0x77, 0x26, 0x4B, 0x7D, 0x20, 0x4A, 0x79, 0x24, 0x4D, 0x7A, 0x39, 0x5A, 0x87, 0x51,

0x6A, 0x94, 0x2E, 0x41, 0x67, 0x26, 0x36, 0x5A, 0x22, 0x2E, 0x52, 0x18, 0x2A, 0x4F, 0x00, 0x1A,

0x46, 0x01, 0x26, 0x5A, 0x23, 0x54, 0x92, 0x30, 0x6A, 0xAC, 0x39, 0x74, 0xB9, 0x31, 0x6A, 0xA8,

0x38, 0x67, 0x9B, 0x22, 0x45, 0x70, 0x15, 0x2C, 0x4C, 0x5C, 0x5F, 0x4F, 0x9A, 0x7E, 0x19, 0xE4,

0xB9, 0x26, 0xF5, 0xCE, 0x30, 0xEA, 0xC4, 0x22, 0xFF, 0xDC, 0x3F, 0xFF, 0xE3, 0x4A, 0xFF, 0xD8,

0x4A, 0xFF, 0xD2, 0x44, 0xFF, 0xD5, 0x3C, 0xF6, 0xD0, 0x2C, 0xF9, 0xD7, 0x29, 0xF9, 0xD5, 0x2D,

0xEC, 0xC4, 0x30, 0xE5, 0xB4, 0x40, 0xBE, 0x88, 0x49, 0xC3, 0x8D, 0x50, 0xCE, 0x96, 0x5F, 0xCE,

0x99, 0x67, 0xCC, 0x9B, 0x6D, 0xC4, 0x9A, 0x75, 0xB5, 0x94, 0x7A, 0xA4, 0x8D, 0x7E, 0x92, 0x83,

0x87, 0x86, 0x7D, 0x92, 0x7E, 0x7C, 0xA0, 0x60, 0x65, 0x96, 0x2A, 0x36, 0x70, 0x0E, 0x21, 0x5E,

0x36, 0x50, 0x8C, 0x3A, 0x59, 0x90, 0x34, 0x59, 0x8D, 0x43, 0x67, 0x95, 0x34, 0x56, 0x81, 0x37,

0x53, 0x7C, 0x10, 0x25, 0x52, 0x33, 0x43, 0x71, 0x5D, 0x68, 0x9A, 0x62, 0x72, 0xA7, 0x57, 0x70,

0xA8, 0x4A, 0x6F, 0xA7, 0x33, 0x65, 0x9F, 0x3C, 0x79, 0xB1, 0x48, 0x88, 0xBE, 0x3C, 0x79, 0xAB,

0x28, 0x59, 0x89, 0x17, 0x3C, 0x68, 0x09, 0x1F, 0x49, 0x3A, 0x3C, 0x44, 0x71, 0x56, 0x1D, 0xB4,

0x90, 0x25, 0xD5, 0xB9, 0x2F, 0xE8, 0xD3, 0x31, 0xF4, 0xDE, 0x2B, 0xFF, 0xF0, 0x38, 0xFF, 0xE6,

0x37, 0xFD, 0xD9, 0x31, 0xFC, 0xD6, 0x32, 0xFE, 0xD5, 0x32, 0xEC, 0xC4, 0x1E, 0xFF, 0xDB, 0x3C,

0xEE, 0xC2, 0x2F, 0xE5, 0xB4, 0x34, 0xB6, 0x7D, 0x40, 0xBD, 0x84, 0x4C, 0xCA, 0x8E, 0x60, 0xC9,

0x91, 0x68, 0xC6, 0x94, 0x70, 0xBC, 0x91, 0x76, 0xAB, 0x88, 0x7A, 0x98, 0x7E, 0x7E, 0x86, 0x73,

0x86, 0x77, 0x6D, 0x91, 0x78, 0x75, 0xA7, 0x35, 0x38, 0x75, 0x00, 0x07, 0x4A, 0x11, 0x21, 0x63,

0x53, 0x6A, 0xA8, 0x63, 0x7E, 0xB6, 0x54, 0x74, 0xA5, 0x51, 0x72, 0x9F, 0x2B, 0x4C, 0x79, 0x04,

0x23, 0x50, 0x00, 0x00, 0x28, 0x2D, 0x40, 0x73, 0x6A, 0x79, 0xB1, 0x5D, 0x70, 0xA9, 0x66, 0x81,

0xBA, 0x71, 0x98, 0xCF, 0x6D, 0xA3, 0xD8, 0x5E, 0x9D, 0xCF, 0x52, 0x94, 0xC5, 0x3D, 0x7B, 0xA9,

0x1F, 0x50, 0x80, 0x1D, 0x41, 0x71, 0x00, 0x16, 0x46, 0x07, 0x0A, 0x26, 0x45, 0x31, 0x20, 0x71,

0x55, 0x18, 0x9B, 0x8B, 0x21, 0xD5, 0xCC, 0x3C, 0xDE, 0xD8, 0x27, 0xFC, 0xF3, 0x32, 0xFC, 0xE9,

0x2E, 0xF7, 0xDC, 0x28, 0xFC, 0xD8, 0x31, 0xFD, 0xD4, 0x37, 0xE6, 0xBA, 0x21, 0xFF, 0xD3, 0x41,

0xF6, 0xC5, 0x3B, 0xE1, 0xAF, 0x2D, 0xAF, 0x72, 0x3A, 0xB9, 0x7B, 0x45, 0xBF, 0x82, 0x56, 0xBF,

0x85, 0x61, 0xBD, 0x89, 0x6B, 0xB1, 0x86, 0x71, 0xA0, 0x7D, 0x79, 0x8D, 0x74, 0x7E, 0x7F, 0x6D,

0x8A, 0x73, 0x6A, 0x95, 0x6F, 0x6D, 0xA8, 0x3A, 0x40, 0x83, 0x09, 0x11, 0x57, 0x0C, 0x1C, 0x5E,

0x3E, 0x52, 0x8C, 0x6C, 0x86, 0xB5, 0x6C, 0x88, 0xB1, 0x57, 0x75, 0x9E, 0x4E, 0x6F, 0xA0, 0x07,

0x27, 0x5C, 0x00, 0x00, 0x2C, 0x16, 0x2C, 0x60, 0x4B, 0x60, 0x94, 0x45, 0x5D, 0x91, 0x6D, 0x8E,

0xC0, 0x96, 0xC1, 0xF4, 0x91, 0xC8, 0xFB, 0x76, 0xB5, 0xE8, 0x56, 0x97, 0xCA, 0x3D, 0x78, 0xAA,

0x1E, 0x4E, 0x82, 0x33, 0x58, 0x8A, 0x14, 0x2B, 0x5D, 0x03, 0x0B, 0x33, 0x23, 0x16, 0x2E, 0x3F,

0x2F, 0x23, 0x62, 0x5D, 0x1E, 0x9C, 0x9D, 0x2F, 0xB0, 0xB6, 0x1B, 0xE8, 0xEB, 0x38, 0xF8, 0xEF,

0x3A, 0xEC, 0xD9, 0x2A, 0xF4, 0xD4, 0x35, 0xF2, 0xC6, 0x35, 0xE4, 0xB4, 0x2C, 0xED, 0xBB, 0x39,

0xF8, 0xC4, 0x48, 0xDA, 0xA5, 0x2D, 0xA7, 0x66, 0x33, 0xAF, 0x70, 0x3E, 0xB3, 0x73, 0x4A, 0xB2,

0x78, 0x54, 0xB0, 0x7E, 0x60, 0xA8, 0x7D, 0x6C, 0x9A, 0x79, 0x76, 0x8C, 0x75, 0x84, 0x85, 0x76,

0x96, 0x7D, 0x77, 0xA8, 0x6F, 0x6E, 0xAC, 0x3A, 0x3F, 0x84, 0x0E, 0x19, 0x5D, 0x0D, 0x1C, 0x5B,

0x05, 0x1A, 0x4D, 0x1F, 0x38, 0x60, 0x3C, 0x56, 0x74, 0x4F, 0x6B, 0x8D, 0x3C, 0x5E, 0x8C, 0x51,

0x75, 0xAB, 0x77, 0x96, 0xCB, 0x58, 0x76, 0xA7, 0x1D, 0x39, 0x68, 0x00, 0x1E, 0x4D, 0x4F, 0x76,

0xA3, 0xAF, 0xDD, 0xFF, 0x97, 0xCF, 0xFF, 0x8C, 0xC9, 0xFB, 0x66, 0xA5, 0xD8, 0x42, 0x7B, 0xAF,

0x1B, 0x49, 0x7F, 0x3F, 0x63, 0x99, 0x25, 0x3C, 0x74, 0x15, 0x21, 0x57, 0x08, 0x06, 0x3A, 0x21,

0x1C, 0x37, 0x39, 0x3B, 0x27, 0x50, 0x58, 0x17, 0x70, 0x79, 0x0B, 0xBC, 0xC0, 0x38, 0xE4, 0xDD,

0x4A, 0xD8, 0xC8, 0x35, 0xE0, 0xC3, 0x39, 0xDA, 0xB3, 0x33, 0xD9, 0xAB, 0x35, 0xD1, 0xA1, 0x31,

0xE6, 0xB3, 0x4B, 0xD0, 0x9D, 0x3C, 0x9F, 0x5B, 0x2E, 0xA6, 0x63, 0x36, 0xA6, 0x69, 0x3D, 0xA8,

0x6F, 0x48, 0xA7, 0x76, 0x56, 0x9F, 0x77, 0x64, 0x95, 0x76, 0x73, 0x8E, 0x7A, 0x87, 0x8E, 0x81,

0xA1, 0x8B, 0x88, 0xB6, 0x70, 0x71, 0xAD, 0x29, 0x32, 0x72, 0x06, 0x12, 0x52, 0x18, 0x29, 0x61,

0x00, 0x0A, 0x35, 0x00, 0x09, 0x27, 0x06, 0x1F, 0x33, 0x24, 0x43, 0x58, 0x1E, 0x45, 0x6B, 0x4B,

0x73, 0xA3, 0xB1, 0xD5, 0xFF, 0xAD, 0xCF, 0xFD, 0xA0, 0xC1, 0xEE, 0x97, 0xBA, 0xE6, 0x96, 0xC1,

0xEC, 0xA5, 0xD6, 0xFF, 0x98, 0xD1, 0xFE, 0xA0, 0xDC, 0xFF, 0x77, 0xB2, 0xE3, 0x45, 0x7C, 0xAF,

0x16, 0x41, 0x7A, 0x3A, 0x5C, 0x98, 0x1A, 0x30, 0x71, 0x0B, 0x1B, 0x5D, 0x00, 0x07, 0x4A, 0x07,

0x10, 0x42, 0x1F, 0x27, 0x3E, 0x2A, 0x32, 0x28, 0x48, 0x4C, 0x22, 0x76, 0x75, 0x31, 0xAE, 0xA4,

0x50, 0xC4, 0xB3, 0x52, 0xD2, 0xB9, 0x53, 0xCD, 0xAE, 0x47, 0xD1, 0xAD, 0x49, 0xC7, 0xA0, 0x44,

0xD3, 0xA7, 0x5A, 0xD7, 0xA9, 0x69, 0x97, 0x52, 0x2B, 0x9C, 0x59, 0x32, 0xA1, 0x62, 0x3C, 0xA1,

0x69, 0x46, 0x9F, 0x6F, 0x53, 0x9A, 0x71, 0x62, 0x91, 0x73, 0x72, 0x8C, 0x79, 0x88, 0x90, 0x85,

0xA6, 0x92, 0x8E, 0xBF, 0x6E, 0x6F, 0xAB, 0x32, 0x3B, 0x7B, 0x12, 0x1E, 0x5E, 0x26, 0x34, 0x6E,

0x0F, 0x1F, 0x4D, 0x17, 0x2C, 0x4C, 0x0D, 0x22, 0x38, 0x00, 0x11, 0x26, 0x00, 0x1F, 0x3F, 0x26,

0x53, 0x79, 0xA4, 0xCE, 0xF8, 0x9E, 0xC5, 0xF1, 0x96, 0xBA, 0xE8, 0x92, 0xB9, 0xE6, 0x82, 0xAF,

0xDB, 0x8C, 0xBD, 0xE9, 0x9A, 0xD1, 0xFC, 0xAA, 0xE4, 0xFF, 0x7C, 0xB3, 0xE0, 0x46, 0x77, 0xA9,

0x14, 0x3C, 0x76, 0x37, 0x55, 0x96, 0x0A, 0x1D, 0x66, 0x00, 0x06, 0x4F, 0x00, 0x15, 0x59, 0x00,

0x08, 0x42, 0x12, 0x22, 0x51, 0x2B, 0x35, 0x53, 0x44, 0x46, 0x51, 0x3D, 0x38, 0x2F, 0x7A, 0x6F,

0x4F, 0xBB, 0xAA, 0x77, 0xCF, 0xBC, 0x79, 0xD1, 0xBA, 0x6F, 0xD1, 0xB9, 0x6D, 0xCB, 0xB0, 0x6D,

0xC7, 0xA8, 0x75, 0xE3, 0xC1, 0x9D, 0x8B, 0x45, 0x27, 0x90, 0x4D, 0x2E, 0x96, 0x55, 0x39, 0x9F,

0x65, 0x4F, 0xA0, 0x6C, 0x5C, 0x91, 0x67, 0x60, 0x8C, 0x6B, 0x72, 0x8D, 0x78, 0x8E, 0x85, 0x78,

0x9E, 0x71, 0x6B, 0xA0, 0x51, 0x50, 0x92, 0x32, 0x36, 0x7D, 0x12, 0x19, 0x62, 0x13, 0x1F, 0x61,

0x29, 0x35, 0x6F, 0x36, 0x46, 0x75, 0x33, 0x43, 0x68, 0x10, 0x2A, 0x48, 0x00, 0x07, 0x1F, 0x0D,

0x3F, 0x5B, 0x93, 0xC1, 0xE3, 0x8F, 0xB9, 0xE3, 0x61, 0x89, 0xB9, 0x5B, 0x83, 0xB7, 0x3F, 0x6A,

0x9B, 0x65, 0x96, 0xC4, 0x90, 0xC4, 0xED, 0x90, 0xC4, 0xED, 0x81, 0xB3, 0xDD, 0x31, 0x5D, 0x8C,

0x00, 0x00, 0x2F, 0x1F, 0x39, 0x7C, 0x53, 0x62, 0xB1, 0x2E, 0x3E, 0x8A, 0x08, 0x29, 0x61, 0x00,

0x15, 0x47, 0x09, 0x20, 0x58, 0x13, 0x20, 0x58, 0x25, 0x29, 0x5A, 0x42, 0x3E, 0x62, 0x58, 0x4E,

0x5B, 0x89, 0x7E, 0x76, 0xAF, 0xA4, 0x86, 0xB8, 0xAD, 0x81, 0xAF, 0xA3, 0x73, 0x99, 0x8D, 0x63,

0x92, 0x86, 0x6A, 0x9B, 0x8B, 0x7E, 0x81, 0x3D, 0x26, 0x88, 0x43, 0x2F, 0x8C, 0x4B, 0x3D, 0x91,

0x53, 0x4D, 0x91, 0x59, 0x58, 0x89, 0x5B, 0x61, 0x85, 0x61, 0x71, 0x84, 0x6B, 0x87, 0x79, 0x68,

0x94, 0x66, 0x5D, 0x96, 0x2B, 0x25, 0x6C, 0x42, 0x42, 0x90, 0x20, 0x22, 0x76, 0x09, 0x10, 0x60,

0x00, 0x05, 0x50, 0x1A, 0x23, 0x67, 0x23, 0x2E, 0x6A, 0x00, 0x10, 0x44, 0x00, 0x13, 0x3D, 0x25,

0x52, 0x77, 0x81, 0xAE, 0xD4, 0x59, 0x85, 0xAE, 0x15, 0x40, 0x6B, 0x0D, 0x37, 0x64, 0x00, 0x2B,

0x5A, 0x1C, 0x47, 0x78, 0x55, 0x7F, 0xB4, 0x7A, 0xA3, 0xDA, 0x56, 0x7C, 0xB6, 0x00, 0x21, 0x5D,

0x04, 0x1F, 0x5F, 0x1E, 0x34, 0x76, 0x55, 0x65, 0xAA, 0x60, 0x75, 0xB3, 0x36, 0x5D, 0x89, 0x16,

0x40, 0x6A, 0x00, 0x13, 0x4A, 0x00, 0x0D, 0x4C, 0x10, 0x19, 0x59, 0x1B, 0x1C, 0x54, 0x35, 0x33,

0x57, 0x52, 0x4F, 0x5F, 0x64, 0x61, 0x5D, 0x5C, 0x5C, 0x4C, 0x51, 0x52, 0x3E, 0x52, 0x52, 0x40,

0x5B, 0x5C, 0x53, 0x59, 0x5B, 0x5C, 0x75, 0x32, 0x23, 0x79, 0x36, 0x2D, 0x80, 0x3C, 0x43, 0x7E,

0x3D, 0x4C, 0x80, 0x45, 0x54, 0x80, 0x4D, 0x61, 0x7E, 0x55, 0x70, 0x7A, 0x59, 0x7E, 0x70, 0x5A,

0x8B, 0x66, 0x57, 0x95, 0x21, 0x14, 0x62, 0x57, 0x4F, 0xA6, 0x3A, 0x36, 0x96, 0x22, 0x21, 0x83,

0x0D, 0x0D, 0x71, 0x05, 0x08, 0x6A, 0x11, 0x16, 0x73, 0x2F, 0x39, 0x91, 0x43, 0x5C, 0xAC, 0x48,

0x6B, 0xAD, 0x4C, 0x74, 0xA8, 0x19, 0x46, 0x6C, 0x00, 0x2B, 0x4A, 0x0D, 0x3C, 0x5B, 0x00, 0x2C,

0x52, 0x00, 0x0C, 0x42, 0x1B, 0x39, 0x80, 0x53, 0x6B, 0xBF, 0x32, 0x45, 0xA0, 0x00, 0x0B, 0x64,

0x13, 0x23, 0x6F, 0x00, 0x0D, 0x4A, 0x05, 0x1A, 0x47, 0x0F, 0x2B, 0x4D, 0x43, 0x6C, 0x85, 0x49,

0x75, 0x92, 0x21, 0x43, 0x6E, 0x1A, 0x32, 0x66, 0x12, 0x23, 0x5C, 0x00, 0x03, 0x37, 0x0C, 0x15,

0x3A, 0x1D, 0x25, 0x3C, 0x14, 0x1D, 0x27, 0x14, 0x1E, 0x25, 0x19, 0x23, 0x2A, 0x1E, 0x27, 0x30,

0x1A, 0x25, 0x2D, 0x0D, 0x1D, 0x24, 0x66, 0x27, 0x1F, 0x6C, 0x2A, 0x2B, 0x72, 0x2E, 0x3F, 0x70,

0x2E, 0x47, 0x74, 0x38, 0x50, 0x7C, 0x48, 0x60, 0x7B, 0x50, 0x6B, 0x77, 0x55, 0x74, 0x78, 0x5D,

0x89, 0x7B, 0x68, 0xA1, 0x2F, 0x21, 0x69, 0x46, 0x3B, 0x91, 0x40, 0x38, 0x9C, 0x1A, 0x15, 0x82,

0x20, 0x1D, 0x90, 0x0C, 0x0C, 0x80, 0x03, 0x03, 0x79, 0x3A, 0x41, 0xB4, 0x6C, 0x7A, 0xEA, 0x73,

0x8B, 0xEB, 0x5B, 0x7B, 0xC4, 0x25, 0x4D, 0x81, 0x07, 0x35, 0x57, 0x28, 0x55, 0x76, 0x58, 0x81,

0xAE, 0x62, 0x80, 0xC1, 0x59, 0x6B, 0xC6, 0x4A, 0x54, 0xBF, 0x23, 0x26, 0x99, 0x21, 0x24, 0x8D,

0x26, 0x2D, 0x7D, 0x50, 0x5E, 0x93, 0x4D, 0x65, 0x7D, 0x3B, 0x5B, 0x68, 0x60, 0x89, 0x98, 0x85,

0xAE, 0xC7, 0x6D, 0x8E, 0xB5, 0x3E, 0x5A, 0x89, 0x14, 0x2B, 0x5D, 0x00, 0x04, 0x31, 0x00, 0x08,

0x29, 0x05, 0x16, 0x30, 0x00, 0x01, 0x16, 0x03, 0x14, 0x29, 0x16, 0x22, 0x3E, 0x13, 0x1F, 0x3B,

0x05, 0x15, 0x2C, 0x03, 0x16, 0x25, 0x5A, 0x1E, 0x1E, 0x5F, 0x21, 0x27, 0x62, 0x21, 0x36, 0x63,

0x25, 0x3D, 0x6D, 0x35, 0x48, 0x79, 0x48, 0x58, 0x7B, 0x52, 0x61, 0x7C, 0x5A, 0x6B, 0x8B, 0x70,

0x8A, 0x9C, 0x87, 0xAE, 0x61, 0x52, 0x8B, 0x28, 0x1D, 0x66, 0x5B, 0x54, 0xAF, 0x1F, 0x1B, 0x85,

0x10, 0x0E, 0x86, 0x18, 0x19, 0x99, 0x0A, 0x0D, 0x93, 0x02, 0x06, 0x8D, 0x00, 0x04, 0x8F, 0x34,

0x3D, 0xBC, 0x59, 0x6D, 0xD2, 0x5E, 0x7C, 0xC9, 0x43, 0x68, 0xA2, 0x3A, 0x60, 0x96, 0x5B, 0x79,

0xBA, 0x60, 0x75, 0xC7, 0x58, 0x5F, 0xCC, 0x20, 0x1D, 0x98, 0x11, 0x08, 0x87, 0x2D, 0x26, 0x95,

0x53, 0x54, 0xA4, 0xAF, 0xBC, 0xE8, 0xAE, 0xC8, 0xCF, 0x93, 0xB3, 0xB2, 0x8E, 0xB2, 0xC2, 0xAC,

0xD0, 0xEE, 0xA9, 0xC7, 0xF0, 0x5A, 0x77, 0xA4, 0x28, 0x43, 0x6F, 0x21, 0x3C, 0x61, 0x15, 0x33,

0x4C, 0x23, 0x3E, 0x53, 0x00, 0x08, 0x20, 0x0E, 0x22, 0x41, 0x24, 0x31, 0x5D, 0x21, 0x2B, 0x5A,

0x22, 0x2D, 0x53, 0x33, 0x42, 0x5C, 0x50, 0x16, 0x1B, 0x55, 0x19, 0x23, 0x56, 0x1B, 0x2A, 0x5C,

0x23, 0x32, 0x6A, 0x37, 0x3F, 0x77, 0x4B, 0x4C, 0x7E, 0x59, 0x55, 0x87, 0x6A, 0x66, 0x9C, 0x85,

0x89, 0xB0, 0x9E, 0xAF, 0xA0, 0x92, 0xB6, 0x18, 0x0F, 0x47, 0x7D, 0x78, 0xC7, 0x6D, 0x6C, 0xCE,

0x14, 0x14, 0x88, 0x04, 0x09, 0x8A, 0x0E, 0x16, 0x9F, 0x00, 0x00, 0x85, 0x02, 0x02, 0x94, 0x00,

0x02, 0x8D, 0x00, 0x09, 0x85, 0x0E, 0x1F, 0x8E, 0x12, 0x26, 0x8B, 0x16, 0x2C, 0x8C, 0x26, 0x35,

0x9B, 0x22, 0x2C, 0x98, 0x32, 0x32, 0xA8, 0x2C, 0x26, 0x9D, 0x3A, 0x31, 0xA0, 0x3A, 0x32, 0x8F,

0x6E, 0x70, 0xB1, 0x70, 0x7B, 0xA1, 0x60, 0x74, 0x7F, 0x55, 0x72, 0x77, 0x43, 0x61, 0x7A, 0x75,

0x92, 0xB9, 0xAF, 0xC7, 0xFB, 0x82, 0x9A, 0xD0, 0x4F, 0x68, 0x9A, 0x4E, 0x6B, 0x92, 0x3E, 0x5F,

0x79, 0x47, 0x68, 0x7C, 0x00, 0x18, 0x32, 0x2F, 0x45, 0x69, 0x54, 0x61, 0x95, 0x51, 0x57, 0x92,

0x49, 0x4D, 0x82, 0x54, 0x5B, 0x82, 0x47, 0x10, 0x19, 0x4C, 0x16, 0x1D, 0x53, 0x1D, 0x22, 0x5B,

0x2A, 0x28, 0x6A, 0x3D, 0x32, 0x78, 0x53, 0x3F, 0x87, 0x69, 0x4E, 0x99, 0x81, 0x65, 0xAB, 0x99,

0x82, 0xB4, 0xA8, 0x9E, 0xB3, 0xAB, 0xB5, 0x2C, 0x29, 0x49, 0x5D, 0x5E, 0x98, 0xA1, 0xA5, 0xF6,

0x59, 0x5F, 0xC8, 0x1F, 0x2A, 0xA3, 0x0C, 0x19, 0x9D, 0x0A, 0x16, 0x9C, 0x11, 0x17, 0x98, 0x05,

0x08, 0x8E, 0x07, 0x0A, 0x9B, 0x05, 0x07, 0xA2, 0x00, 0x00, 0xA0, 0x03, 0x00, 0xA4, 0x0A, 0x06,

0xA1, 0x11, 0x0E, 0x99, 0x3D, 0x3A, 0xAD, 0x51, 0x50, 0xAC, 0x2E, 0x2E, 0x74, 0x34, 0x37, 0x6A,

0x5A, 0x60, 0x89, 0x1C, 0x25, 0x46, 0x1F, 0x29, 0x47, 0x28, 0x37, 0x58, 0x1C, 0x2F, 0x5A, 0x47,

0x5C, 0x93, 0x8E, 0x9F, 0xE2, 0x90, 0xA2, 0xE9, 0x5F, 0x73, 0xB4, 0x4E, 0x69, 0x9C, 0x59, 0x7A,

0x9B, 0x5C, 0x7E, 0x96, 0x1E, 0x3B, 0x56, 0x54, 0x6A, 0x8E, 0x86, 0x8F, 0xC8, 0x8D, 0x8C, 0xCE,

0x7F, 0x79, 0xBA, 0x7E, 0x78, 0xAF, 0x3D, 0x0E, 0x17, 0x43, 0x13, 0x19, 0x54, 0x24, 0x23, 0x5D,

0x2F, 0x28, 0x6A, 0x42, 0x30, 0x7B, 0x58, 0x3E, 0x90, 0x74, 0x52, 0xA7, 0x8F, 0x6B, 0xB5, 0xA2,

0x81, 0xB4, 0xA8, 0x90, 0xBA, 0xB2, 0xAB, 0x6E, 0x6C, 0x78, 0x30, 0x32, 0x55, 0x9F, 0xA3, 0xDE,

0xC1, 0xCA, 0xFF, 0x95, 0xA1, 0xFF, 0x35, 0x42, 0xAE, 0x28, 0x36, 0xA7, 0x18, 0x22, 0x97, 0x0A,

0x13, 0x92, 0x13, 0x1A, 0xAD, 0x0C, 0x0D, 0xB1, 0x07, 0x04, 0xB4, 0x19, 0x12, 0xC1, 0x20, 0x17,

0xB4, 0x2F, 0x23, 0xA5, 0x76, 0x6B, 0xC7, 0x7E, 0x72, 0xAE, 0x29, 0x1C, 0x3C, 0x8D, 0x81, 0x93,

0xC2, 0xB9, 0xC6, 0xA2, 0x9A, 0xAB, 0xB5, 0xAC, 0xC6, 0xA1, 0xA0, 0xC2, 0xA1, 0xAA, 0xD6, 0x8B,

0x9B, 0xD0, 0x8A, 0x99, 0xD8, 0x95, 0xA7, 0xE8, 0x6A, 0x80, 0xBA, 0x5C, 0x76, 0xA5, 0x8B, 0xAA,

0xC9, 0x88, 0xA7, 0xBC, 0x4D, 0x64, 0x7A, 0x6D, 0x7B, 0x98, 0x97, 0x98, 0xC4, 0xB4, 0xAC, 0xE1,

0xBF, 0xB2, 0xE6, 0xC3, 0xB3, 0xE2, 0x34, 0x0E, 0x14, 0x3B, 0x12, 0x17, 0x4C, 0x20, 0x21, 0x5F,

0x32, 0x2F, 0x77, 0x4C, 0x43, 0x87, 0x60, 0x51, 0x90, 0x6E, 0x57, 0x98, 0x7B, 0x60, 0xA0, 0x89,

0x6F, 0xA6, 0x94, 0x7D, 0xAD, 0xA0, 0x92, 0x83, 0x7B, 0x7B, 0x4F, 0x4A, 0x59, 0x45, 0x45, 0x63,

0x84, 0x87, 0xB4, 0xC8, 0xCC, 0xFF, 0xBF, 0xC5, 0xFF, 0x82, 0x8D, 0xDF, 0x4B, 0x5C, 0xC3, 0x33,

0x47, 0xBE, 0x24, 0x3A, 0xB8, 0x19, 0x2E, 0xB2, 0x10, 0x20, 0xA8, 0x20, 0x29, 0xA8, 0x44, 0x42,

0xAC, 0x63, 0x56, 0xA6, 0x54, 0x3A, 0x6A, 0x29, 0x03, 0x19, 0x7F, 0x50, 0x52, 0xD8, 0xA7, 0x9D,

0xD1, 0xA4, 0x97, 0xE7, 0xBD, 0xB1, 0xFF, 0xE5, 0xE1, 0xFD, 0xE5, 0xED, 0xE5, 0xE2, 0xFC, 0xCC,

0xD8, 0xFC, 0x9D, 0xAF, 0xD4, 0xA3, 0xBB, 0xDF, 0x9D, 0xBA, 0xD9, 0x6C, 0x8B, 0xA4, 0x7A, 0x98,

0xA9, 0xA7, 0xBF, 0xCB, 0xB1, 0xBD, 0xC7, 0xB9, 0xB9, 0xC5, 0xCE, 0xC3, 0xD3, 0xEE, 0xDC, 0xED,

0xFF, 0xF2, 0xFF, 0xFF, 0xF9, 0xFF, 0x33, 0x13, 0x18, 0x3D, 0x18, 0x1C, 0x53, 0x28, 0x2B, 0x63,

0x35, 0x34, 0x75, 0x48, 0x44, 0x82, 0x5A, 0x4E, 0x8B, 0x67, 0x57, 0x90, 0x6F, 0x5C, 0x94, 0x77,

0x62, 0x93, 0x7B, 0x69, 0x93, 0x7E, 0x6F, 0x96, 0x86, 0x7F, 0x7D, 0x6F, 0x73, 0x47, 0x3D, 0x4D,

0x34, 0x2D, 0x48, 0x5B, 0x55, 0x78, 0x91, 0x8D, 0xB7, 0xA7, 0xA8, 0xE2, 0x90, 0x9C, 0xEA, 0x95,

0xA7, 0xFF, 0x83, 0x99, 0xF9, 0x65, 0x7B, 0xDB, 0x67, 0x79, 0xD8, 0x77, 0x82, 0xD4, 0x64, 0x60,

0xA1, 0x40, 0x2E, 0x57, 0x35, 0x11, 0x1F, 0x72, 0x41, 0x39, 0xCC, 0x8E, 0x76, 0xDE, 0x9D, 0x7E,

0xCD, 0x90, 0x6E, 0xE0, 0xA9, 0x8A, 0xF5, 0xC5, 0xAD, 0xF3, 0xD3, 0xC8, 0xF2, 0xE8, 0xF4, 0xC1,

0xC8, 0xDC, 0xB4, 0xC3, 0xD6, 0xCC, 0xE3, 0xF3, 0xBB, 0xD6, 0xE4, 0x90, 0xAD, 0xB6, 0x9F, 0xB5,

0xBB, 0xC4, 0xD0, 0xD4, 0xEA, 0xE7, 0xE9, 0xE0, 0xD2, 0xD3, 0xD3, 0xBC, 0xBA, 0xCB, 0xAE, 0xAA,

0xC3, 0xA7, 0xA0, 0xB9, 0xA0, 0x96, 0x34, 0x19, 0x1D, 0x3F, 0x1E, 0x22, 0x58, 0x30, 0x32, 0x62,

0x36, 0x35, 0x6B, 0x41, 0x3C, 0x76, 0x4C, 0x45, 0x7E, 0x56, 0x4A, 0x80, 0x5B, 0x4D, 0x7D, 0x5A,

0x4C, 0x78, 0x58, 0x4B, 0x77, 0x5A, 0x51, 0x7F, 0x64, 0x60, 0x7A, 0x63, 0x68, 0x68, 0x53, 0x62,

0x65, 0x51, 0x68, 0x76, 0x64, 0x83, 0x8C, 0x7B, 0xA0, 0x92, 0x86, 0xB0, 0x55, 0x50, 0x7D, 0x5C,

0x5C, 0x8C, 0x55, 0x59, 0x8E, 0x52, 0x57, 0x8E, 0x52, 0x57, 0x8E, 0x44, 0x42, 0x70, 0x3C, 0x2F,

0x4F, 0x52, 0x38, 0x45, 0xA4, 0x7C, 0x70, 0xB5, 0x83, 0x65, 0xD1, 0x95, 0x6B, 0xBC, 0x81, 0x50,

0xB0, 0x78, 0x49, 0xD5, 0xA4, 0x78, 0xF3, 0xC9, 0xA4, 0xF8, 0xDB, 0xC6, 0xAE, 0xA4, 0xA4, 0x8E,

0x90, 0x9A, 0xBF, 0xC8, 0xD1, 0xF1, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xD9, 0xE9, 0xE8, 0xB7, 0xBF,

0xBE, 0x9D, 0x9C, 0x98, 0xB3, 0xA2, 0x9F, 0xB1, 0x94, 0x8F, 0xA7, 0x81, 0x7C, 0x9D, 0x73, 0x6C,

0x90, 0x67, 0x5E, 0x85, 0x5F, 0x53, 0x34, 0x1D, 0x21, 0x40, 0x23, 0x26, 0x53, 0x2E, 0x30, 0x5A,

0x31, 0x2F, 0x5E, 0x35, 0x32, 0x63, 0x3B, 0x36, 0x68, 0x3E, 0x37, 0x68, 0x41, 0x39, 0x68, 0x41,

0x39, 0x66, 0x40, 0x3B, 0x7C, 0x57, 0x53, 0x77, 0x52, 0x54, 0x6E, 0x4C, 0x53, 0x67, 0x46, 0x54,

0x64, 0x43, 0x58, 0x67, 0x47, 0x60, 0x6E, 0x4F, 0x6E, 0x76, 0x59, 0x73, 0x5F, 0x46, 0x54, 0x44,

0x2F, 0x38, 0x26, 0x15, 0x23, 0x2B, 0x1D, 0x2F, 0x2F, 0x20, 0x35, 0x23, 0x12, 0x20, 0x65, 0x4A,

0x4D, 0xE2, 0xBF, 0xB2, 0xE8, 0xB9, 0x9A, 0xAF, 0x78, 0x4D, 0xB3, 0x77, 0x41, 0xAE, 0x73, 0x3B,

0x9E, 0x6A, 0x35, 0xD2, 0xA4, 0x74, 0xE5, 0xC1, 0x99, 0xB4, 0x99, 0x7E, 0x67, 0x5B, 0x4F, 0x9A,

0x97, 0x93, 0xF3, 0xF4, 0xF0, 0xF2, 0xF6, 0xF0, 0xCA, 0xCF, 0xC6, 0xBD, 0xBE, 0xB4, 0x9E, 0x95,

0x8C, 0x8C, 0x79, 0x71, 0x99, 0x78, 0x6F, 0x9F, 0x71, 0x69, 0xA0, 0x6B, 0x61, 0x9D, 0x65, 0x5A,

0x93, 0x5E, 0x51, 0x88, 0x54, 0x47, 0x2E, 0x1D, 0x20, 0x38, 0x22, 0x24, 0x46, 0x26, 0x27, 0x4F,

0x29, 0x29, 0x51, 0x2B, 0x29, 0x51, 0x2A, 0x28, 0x52, 0x29, 0x27, 0x55, 0x2C, 0x2A, 0x5D, 0x31,

0x30, 0x62, 0x36, 0x37, 0x75, 0x46, 0x49, 0x6B, 0x3A, 0x42, 0x5F, 0x30, 0x39, 0x56, 0x28, 0x35,

0x4C, 0x1C, 0x2E, 0x47, 0x19, 0x2C, 0x56, 0x27, 0x3D, 0x6D, 0x3D, 0x49, 0x72, 0x41, 0x33, 0x75,

0x45, 0x2D, 0x64, 0x39, 0x28, 0x69, 0x41, 0x35, 0x77, 0x50, 0x47, 0x71, 0x49, 0x3D, 0x8E, 0x63,

0x50, 0xD9, 0xA7, 0x89, 0xC9, 0x8F, 0x65, 0xAA, 0x6B, 0x38, 0xB0, 0x70, 0x39, 0x9C, 0x5F, 0x27,

0x8C, 0x57, 0x24, 0xC8, 0x9B, 0x6F, 0xD7, 0xB3, 0x8F, 0x9D, 0x83, 0x65, 0xAF, 0x9E, 0x89, 0xD8,

0xCE, 0xBD, 0xEA, 0xE2, 0xD1, 0xAC, 0xA2, 0x90, 0x8A, 0x7E, 0x6C, 0x8D, 0x7C, 0x69, 0x7E, 0x62,

0x51, 0x8D, 0x66, 0x57, 0xA8, 0x75, 0x65, 0xA7, 0x6A, 0x5C, 0x9F, 0x5B, 0x4E, 0x97, 0x52, 0x43,

0x8F, 0x4C, 0x3D, 0x86, 0x48, 0x38, 0x24, 0x19, 0x1B, 0x2D, 0x1D, 0x1E, 0x36, 0x1E, 0x1E, 0x3F,

0x21, 0x20, 0x41, 0x21, 0x22, 0x42, 0x20, 0x21, 0x44, 0x1D, 0x1F, 0x49, 0x20, 0x25, 0x54, 0x28,

0x2E, 0x5F, 0x2E, 0x36, 0x5C, 0x29, 0x31, 0x52, 0x1D, 0x27, 0x52, 0x1A, 0x25, 0x5A, 0x22, 0x2F,

0x62, 0x27, 0x35, 0x5F, 0x24, 0x32, 0x62, 0x27, 0x35, 0x70, 0x32, 0x32, 0x85, 0x41, 0x24, 0x83,

0x3E, 0x17, 0x67, 0x26, 0x07, 0x5A, 0x1D, 0x03, 0x63, 0x29, 0x13, 0x72, 0x38, 0x22, 0x97, 0x5B,

0x3E, 0xCD, 0x8D, 0x6B, 0xBB, 0x76, 0x4E, 0xAE, 0x68, 0x39, 0x9C, 0x57, 0x26, 0x85, 0x45, 0x15,

0x94, 0x5B, 0x34, 0xB6, 0x87, 0x67, 0xC6, 0x9E, 0x85, 0xD9, 0xBA, 0xA3, 0xE5, 0xCE, 0xB4, 0xD4,

0xC1, 0xA6, 0xA5, 0x90, 0x75, 0x7A, 0x63, 0x49, 0x8E, 0x70, 0x57, 0x95, 0x71, 0x59, 0x7C, 0x4D,

0x37, 0x7E, 0x47, 0x32, 0x97, 0x55, 0x43, 0x94, 0x4E, 0x3D, 0x8D, 0x42, 0x32, 0x85, 0x3A, 0x2A,

0x7F, 0x39, 0x28, 0x79, 0x38, 0x29, 0x18, 0x13, 0x14, 0x1E, 0x16, 0x16, 0x28, 0x19, 0x17, 0x2C,

0x18, 0x17, 0x2F, 0x17, 0x19, 0x32, 0x17, 0x1B, 0x38, 0x18, 0x1D, 0x3F, 0x1A, 0x22, 0x47, 0x1D,

0x28, 0x4C, 0x1E, 0x2A, 0x52, 0x20, 0x2C, 0x52, 0x1C, 0x29, 0x53, 0x19, 0x24, 0x4F, 0x12, 0x1C,

0x45, 0x06, 0x0F, 0x44, 0x04, 0x0A, 0x56, 0x16, 0x1C, 0x77, 0x31, 0x2A, 0x79, 0x26, 0x0A, 0x75,

0x1F, 0x00, 0x72, 0x20, 0x01, 0x7A, 0x2A, 0x11, 0x75, 0x29, 0x16, 0x75, 0x2C, 0x18, 0x9E, 0x52,

0x3C, 0xD3, 0x86, 0x6C, 0xA6, 0x58, 0x3B, 0x89, 0x3C, 0x1C, 0x7B, 0x30, 0x10, 0x7F, 0x3B, 0x1E,

0x99, 0x5C, 0x48, 0xA4, 0x6F, 0x62, 0xA3, 0x75, 0x6E, 0xC2, 0x9B, 0x92, 0xA8, 0x86, 0x6E, 0xAA,

0x8B, 0x6A, 0x97, 0x73, 0x55, 0x8C, 0x64, 0x47, 0x8E, 0x5F, 0x43, 0x89, 0x53, 0x3A, 0x88, 0x4A,

0x32, 0x7E, 0x3B, 0x26, 0x91, 0x47, 0x35, 0x93, 0x46, 0x36, 0x8E, 0x41, 0x31, 0x80, 0x37, 0x29,

0x74, 0x31, 0x22, 0x68, 0x2B, 0x1D, 0x10, 0x10, 0x10, 0x13, 0x11, 0x11, 0x19, 0x14, 0x13, 0x1A,

0x10, 0x10, 0x1C, 0x0E, 0x10, 0x22, 0x11, 0x15, 0x2D, 0x16, 0x1E, 0x35, 0x17, 0x22, 0x37, 0x14,

0x22, 0x38, 0x0F, 0x1E, 0x45, 0x16, 0x26, 0x3D, 0x0B, 0x17, 0x39, 0x01, 0x0C, 0x41, 0x06, 0x0E,

0x4B, 0x0E, 0x12, 0x50, 0x11, 0x13, 0x54, 0x14, 0x14, 0x60, 0x17, 0x0F, 0x6A, 0x14, 0x00, 0x6C,

0x10, 0x00, 0x6D, 0x16, 0x00, 0x6F, 0x19, 0x05, 0x67, 0x14, 0x05, 0x70, 0x1E, 0x12, 0x91, 0x3E,

0x2F, 0xA8, 0x56, 0x45, 0x9E, 0x4C, 0x3A, 0x78, 0x29, 0x16, 0x7C, 0x2E, 0x1D, 0x71, 0x2A, 0x1C,

0x6B, 0x2C, 0x24, 0x97, 0x5F, 0x5E, 0xA6, 0x73, 0x7A, 0x8E, 0x63, 0x60, 0x99, 0x6F, 0x58, 0xA0,

0x75, 0x54, 0x90, 0x61, 0x42, 0x88, 0x54, 0x36, 0x77, 0x3C, 0x22, 0x84, 0x41, 0x2A, 0x99, 0x52,

0x3E, 0x69, 0x1F, 0x0D, 0x7D, 0x30, 0x20, 0x7E, 0x33, 0x25, 0x73, 0x2D, 0x20, 0x5F, 0x1F, 0x14,

0x52, 0x18, 0x0C, 0x4C, 0x1A, 0x0E, 0x04, 0x06, 0x06, 0x13, 0x15, 0x15, 0x0A, 0x0D, 0x0B, 0x0D,

0x0E, 0x0C, 0x11, 0x0F, 0x0F, 0x17, 0x10, 0x13, 0x1D, 0x10, 0x18, 0x23, 0x0F, 0x1B, 0x28, 0x10,

0x1C, 0x2D, 0x0F, 0x1C, 0x2D, 0x09, 0x17, 0x33, 0x08, 0x15, 0x38, 0x09, 0x12, 0x3C, 0x08, 0x0F,

0x3F, 0x08, 0x0B, 0x42, 0x09, 0x08, 0x43, 0x09, 0x04, 0x4C, 0x09, 0x00, 0x60, 0x12, 0x02, 0x60,

0x0C, 0x00, 0x5E, 0x0B, 0x00, 0x60, 0x10, 0x05, 0x64, 0x13, 0x0C, 0x6A, 0x1A, 0x13, 0x7F, 0x2F,

0x28, 0x97, 0x47, 0x40, 0x85, 0x36, 0x2D, 0x68, 0x1B, 0x12, 0x66, 0x1B, 0x13, 0x5D, 0x19, 0x14,

0x79, 0x3B, 0x3B, 0x81, 0x49, 0x4E, 0x93, 0x5F, 0x69, 0x87, 0x56, 0x58, 0x87, 0x57, 0x45, 0x92,

0x60, 0x42, 0x8E, 0x55, 0x3B, 0x7D, 0x3F, 0x27, 0x78, 0x35, 0x20, 0x7E, 0x36, 0x24, 0x7B, 0x30,

0x20, 0x6C, 0x23, 0x15, 0x65, 0x1E, 0x14, 0x6A, 0x29, 0x20, 0x64, 0x2B, 0x22, 0x50, 0x1F, 0x17,

0x3E, 0x14, 0x0D, 0x39, 0x15, 0x0D};

 

flash unsigned char compImg[864] = {

/*

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x55, 0x00, 0x00, 0x55, 0x55, 0x55, 0x50, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x65, 0x40, 0x05, 0x55, 0xE6, 0x65, 0x55, 0x55, 0x05, 0x55, 0x40, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x05, 0x65, 0x55, 0x55, 0x6E, 0xEF, 0xF6, 0x15, 0x51, 0x15, 0x55, 0x40, 0x00, 0x00,

0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x11, 0x15, 0xE6, 0x55, 0x55, 0x6E, 0x6E, 0xFF, 0xE5, 0x51, 0x55, 0x55, 0x55, 0x51, 0x00,

0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x01, 0xEE, 0x55, 0x55, 0x6F, 0x61, 0xEF, 0xFF, 0xEE, 0x55, 0x55, 0x55, 0x51, 0x11,

0x01, 0x11, 0x51, 0x11, 0x11, 0x11, 0x9D, 0xE1, 0x99, 0x99, 0x10, 0x05, 0x66, 0x65, 0x6F, 0xFE, 0xEF, 0xFF, 0xFE, 0xEE, 0xE6, 0x55, 0x55, 0x55,

0x01, 0x55, 0x55, 0x55, 0x61, 0x00, 0x1E, 0xEE, 0xEE, 0x99, 0xA9, 0x00, 0x16, 0x66, 0xEF, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF, 0xFE, 0xEE, 0xEE, 0xEE,

0x01, 0x55, 0x56, 0x6E, 0x51, 0x1E, 0xFF, 0xE9, 0x98, 0x88, 0x89, 0x90, 0x01, 0xEE, 0xEF, 0xFF, 0xFE, 0xEE, 0xAA, 0xEE, 0xEF, 0xFF, 0xFF, 0xFF,

0x01, 0x15, 0x6E, 0xEE, 0x10, 0xEF, 0xE9, 0x88, 0x88, 0x88, 0x88, 0x89, 0x90, 0xEE, 0xEE, 0xEE, 0xEE, 0xEA, 0x9E, 0xE1, 0x9E, 0xEE, 0xEE, 0xFF,

0x00, 0x15, 0x6E, 0xEE, 0x09, 0xE9, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x90, 0x09, 0x00, 0x00, 0x9E, 0xE9, 0x99, 0x90, 0x9E, 0xE9, 0x9E, 0xEE,

0x00, 0x11, 0x5E, 0xEE, 0x09, 0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x89, 0x91, 0x11, 0xAF, 0xE9, 0x91, 0x10, 0x19, 0x99, 0x99, 0x9A,

0x00, 0x11, 0x1D, 0xE9, 0x09, 0x88, 0x88, 0x88, 0x89, 0x99, 0x99, 0x99, 0x88, 0x89, 0xEF, 0xEE, 0xFF, 0x91, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,

0x00, 0x11, 0x19, 0x90, 0x88, 0x88, 0x80, 0x99, 0xA9, 0x90, 0x1A, 0xA9, 0x98, 0x80, 0x91, 0x1A, 0xEA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x05, 0x51, 0x19, 0x90, 0x98, 0x80, 0x00, 0x89, 0x99, 0x10, 0x00, 0x08, 0x99, 0x00, 0x00, 0x09, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x55, 0x55, 0xD9, 0x90, 0x90, 0x00, 0x00, 0x00, 0x1E, 0xA1, 0x00, 0x19, 0xA9, 0x00, 0x09, 0x99, 0x10, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00,

0x55, 0x55, 0xDD, 0x99, 0x00, 0x00, 0x11, 0x00, 0x0F, 0xEA, 0xA9, 0xAF, 0xFE, 0x90, 0x09, 0x80, 0x00, 0x00, 0x01, 0x5E, 0xE6, 0x66, 0x6E, 0x10,

0x55, 0x55, 0xDE, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0xEE, 0xEF, 0xFA, 0x90, 0x90, 0x00, 0x00, 0x01, 0x01, 0x66, 0x66, 0x66, 0xF6, 0x55,

0x55, 0x55, 0xDE, 0xE9, 0x00, 0x00, 0x00, 0x11, 0x9F, 0xFF, 0xEF, 0xFF, 0xFA, 0x91, 0x90, 0x00, 0x00, 0x01, 0x16, 0x66, 0x66, 0x66, 0x66, 0x55,

0x55, 0x55, 0xDD, 0x99, 0x80, 0x00, 0x01, 0x99, 0x9A, 0x90, 0x09, 0xFF, 0xFA, 0x91, 0x90, 0x00, 0x00, 0x11, 0x77, 0x77, 0x66, 0x66, 0x66, 0x65,

0x66, 0x65, 0x59, 0x99, 0x90, 0x09, 0xAA, 0x99, 0x00, 0x09, 0x9A, 0xFF, 0xAA, 0x99, 0x90, 0x00, 0x01, 0x66, 0x77, 0x77, 0x76, 0x67, 0x66, 0x66,

0x66, 0x66, 0x5D, 0x99, 0x00, 0x09, 0x99, 0x91, 0x00, 0x19, 0x9A, 0xAA, 0xAA, 0x99, 0x10, 0x00, 0x16, 0x77, 0x77, 0x77, 0x76, 0x77, 0x66, 0x66,

0x66, 0x66, 0x6E, 0xD9, 0x90, 0x09, 0x99, 0x99, 0x10, 0x19, 0x99, 0x99, 0x9A, 0x99, 0x00, 0x01, 0x66, 0x77, 0x77, 0x77, 0x77, 0x77, 0x66, 0x6F,

0x66, 0x66, 0x66, 0xE9, 0xE9, 0x01, 0x11, 0x19, 0x91, 0x00, 0x00, 0x09, 0x99, 0x99, 0x10, 0x15, 0x67, 0x77, 0x77, 0x77, 0x77, 0x77, 0x66, 0xEE,

0x66, 0x66, 0x66, 0x69, 0x91, 0x09, 0x10, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x10, 0x16, 0x67, 0x67, 0x77, 0x77, 0x77, 0x76, 0x66, 0xEA,

0x66, 0x66, 0x66, 0x61, 0x91, 0x01, 0x10, 0x00, 0x00, 0x01, 0x9A, 0xA9, 0x99, 0x99, 0x11, 0x06, 0x66, 0x77, 0x67, 0x77, 0x77, 0x66, 0x2E, 0x99,

0x66, 0x66, 0x6E, 0xEE, 0x91, 0x00, 0x10, 0x00, 0x00, 0x99, 0x90, 0x09, 0x99, 0x91, 0x11, 0x05, 0x66, 0x67, 0x77, 0x76, 0x66, 0x11, 0x99, 0x99,

0x66, 0x66, 0x66, 0x51, 0x11, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x10, 0x11, 0x00, 0x56, 0x76, 0x66, 0x65, 0x51, 0x11, 0x99, 0x10,

0x66, 0x66, 0x66, 0x51, 0x11, 0x11, 0x10, 0x00, 0x00, 0x00, 0x01, 0xAA, 0x91, 0x00, 0x19, 0x00, 0x56, 0x66, 0x66, 0x60, 0x19, 0x91, 0x91, 0x00,

0x66, 0x66, 0x66, 0x65, 0x51, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x10, 0x56, 0x66, 0x67, 0x50, 0x99, 0x90, 0x11, 0x00,

0x66, 0x66, 0x66, 0x65, 0x51, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x15, 0x55, 0x55, 0x6E, 0x01, 0x99, 0x90, 0x00, 0x00,

0x66, 0x66, 0x66, 0x65, 0x51, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x95, 0x50, 0x1F, 0xF5, 0x09, 0x99, 0x00, 0x00, 0x00,

0x77, 0x66, 0x66, 0x65, 0x55, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x91, 0xD0, 0x01, 0xFF, 0xED, 0x09, 0xA9, 0x00, 0x00, 0x00,

0x77, 0x66, 0x66, 0x65, 0x55, 0x51, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x91, 0x00, 0x5F, 0xFF, 0xE1, 0x09, 0x99, 0x00, 0x00, 0x00,

0x76, 0x66, 0x66, 0x65, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x0D, 0xEE, 0xFE, 0xE1, 0x09, 0x91, 0x00, 0x00, 0x80,

0x66, 0x66, 0x66, 0x65, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xDE, 0xDE, 0xFF, 0xF1, 0x01, 0x11, 0x00, 0x00, 0x00

*/

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  

};

 

inline void Write_Byte_MMC(UCHAR Byte)

{

    SPDR = Byte;

    while(!(SPSR & (1<<SPIF)));

}  

inline UCHAR Read_Byte_MMC(void)

{

    UCHAR Byte;

    SPDR = 0xff;

 

    while(!(SPSR & (1<<SPIF)));

 

    Byte = SPDR;   

    return (Byte);

}

 

UCHAR Write_Command_MMC(UCHAR *CMD)

{

    UCHAR a;

    UCHAR tmp = 0xff;

    UCHAR Timeout = 0;

 

    // Raise chip select

    MMC_Disable();

 

    // Send an 8 bit pulse

    Write_Byte_MMC(0xFF);

 

    // Lower chip select

    MMC_Enable();

 

    // Send the 6 byte command

    for (a = 0;a<0x06;a++)

    {

        Write_Byte_MMC(*CMD++);

    }

 

    // Wait for the response

    while (tmp == 0xff)

    {

        tmp = Read_Byte_MMC();

        if (Timeout++ > 100)

        {

            break;

        }

    }

    // for some reason we need to delay here

    delay_ms(1);

 

    return(tmp);

}

 

 

UCHAR MmcInit()

{

    UCHAR a,b, retry;

    UCHAR CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};

 

    // Set certain pins to inputs and others to outputs

    // Only SPI_DI (data in) is an input

    MMC_Direction_REG &=~(1<<SPI_DI);

    MMC_Direction_REG |= (1<<SPI_Clock);

    MMC_Direction_REG |= (1<<SPI_DO);

    MMC_Direction_REG |= (1<<MMC_Chip_Select);

    MMC_Direction_REG |= (1<<SPI_SS);

    MMC_Write |= (1<<MMC_Chip_Select);

 

    // We need to wait for the MMC_Direction_REG to be ready

    for(a=0;a<200;a++)

    {

        nop();

    };

 

    // Enable SPI in Master Mode with IDLE low and clock at 16E6/128

    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);

    SPSR = (0<<SPI2X);

 

    // We need to give the card about a hundred cycles to load

    for (b = 0; b < 0x0f; ++b)

    {

        Write_Byte_MMC(0xff);

    }

   

    // Send the initialization commands to the card

    retry = 0;

 

    // Note, many examples check for (Write_Command_MMC(CMD) == R1_IN_IDLE_STATE)

    // However, with our setup the card was in IDLE state and returning another command

    while((Write_Command_MMC(CMD) & R1_IN_IDLE_STATE) == 0)

    {

        // fail and return

        if (retry++ > 50)

        {

            return 1;

        }

    }

 

    // Send the 2nd command

    retry = 0;

    CMD[0] = 0x41;

    CMD[5] = 0xFF;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 2;

        }

    }

/*

    retry = 0;

    CMD[0] = 0x50;

    CMD[5] = 0xFF;

    CMD[3] = 0x02;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 2;

        }

    }

*/

    // Set the SPI bus to full speed

    SPCR = SPCR|(0<<SPR0)|(0<<SPR1);

    SPSR = SPSR|(1<<SPI2X);

   

    // Raise Chip Select

    MMC_Disable();

   

    return 0;

}

 

UCHAR mmc_write_sector (unsigned long addr,UCHAR *Buffer,UINT Blocksize)

{

    UCHAR tmp;

    UINT a;

 

    // Command to write a block to the memory card

    UCHAR CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};

 

    // Encode the address to a 32-bit address

    // Ignore the bottom byte of the address as we give the address of the sector

    CMD[1] = ((addr & 0xFF000000) >> 24);

    CMD[2] = ((addr & 0x00FF0000) >> 16);

    CMD[3] = ((addr & 0x0000FF00) >> 8);

    CMD[4] =   addr & 0x000000FF;

    // Send the write command

    tmp = Write_Command_MMC (CMD);

    if (tmp != 0)

    {

        return(tmp);

    }

           

    // Wait a little bit

    for (a = 0; a < 100; ++a)

    {

        Read_Byte_MMC();

    }

 

    // Send the start byte

    Write_Byte_MMC(0xFE);  

 

    // Send all bytes in the buffer

    for (a = 0; a < Blocksize; ++a)

    {

        Write_Byte_MMC(*Buffer++);

    }

 

    // Write CRC byte

    Write_Byte_MMC(0xFF);

    Write_Byte_MMC(0xFF);

 

    // Wait for the write to complete

    while (Read_Byte_MMC() != 0xff);

 

    // Set MMC_Chip_Select to high

    MMC_Disable();

 

    return(0);

}

 

UCHAR MMC_Read_Block(UCHAR *CMD,UCHAR *Buffer,UINT Bytes)

{  

    UINT a;

    UCHAR temp;

 

    // Send the read command

    if (temp = Write_Command_MMC(CMD) != 0)

    {

        return;

    }

           

    // Send the start byte

    while (Read_Byte_MMC() != 0xfe);

 

    // Read off all the bytes in the block

    for (a = 0; a < Bytes; ++a)

    {

        PORTA=0xff;

        *Buffer++ = Read_Byte_MMC();

        PORTA=0x00;

    }

 

    // Read CRC byte

    Read_Byte_MMC();

    Read_Byte_MMC();

 

    // Set MMC_Chip_Select to high

    MMC_Disable();

 

    return;

}

UCHAR set_blocksize (UINT Blocksize)

{  

    char retry;

    // Command to set blocksize

    UCHAR CMD[] = {0x50,0x00,0x00,0x00,0x00,0xFF};

    CMD[1] = ((Blocksize & 0xFF000000) >> 24);

    CMD[2] = ((Blocksize & 0x00FF0000) >> 16);

    CMD[3] = ((Blocksize & 0x0000FF00) >> 8);

    CMD[4] =   Blocksize & 0x000000FF;

    retry = 0;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 1;

        }

    }

    MMC_Disable();

    return 0;

}

UCHAR mmc_read_sector (unsigned long addr, UCHAR *Buffer, UINT Blocksize)

{  

    // Command to read a 512-byte sector

    UCHAR CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};

 

    // Encode the address to a 32-bit address

    // Ignore the bottom byte of the address as we give the address of the sector

     

    //addr = addr << 9; //addr = addr * 512

 

    CMD[1] = ((addr & 0xFF000000) >> 24);

    CMD[2] = ((addr & 0x00FF0000) >> 16);

    CMD[3] = ((addr & 0x0000FF00) >> 8);

    CMD[4] =   addr & 0x000000FF;

 

    MMC_Read_Block(CMD,Buffer,Blocksize);

 

    return(0);

}

 

void main(){       

        unsigned int i,j;

 

        //UCHAR CMD[] = {0x5D,0x00,0x00,0x00,0x00,0xFF};

        DDRA = 0xff;

        PORTA = 0xf0;

       

        if(MmcInit()==0) PORTA = 0x0f;

        delay_ms(2000);

               

      //  try to write several blocks

      set_blocksize(512);

      for(i=0;i<512;i++) screen[i]=compImg[i];

      mmc_write_sector(1024,screen,512);

 

      for(i=0;i<352;i++) screen[i]=compImg[i+512];

      mmc_write_sector(1536,screen,512);

 

      for(i=0;i<512;i++) screen[i]=0;

      mmc_read_sector(0,screen,512);

      for(i=512;i>0;i--) {

        PORTA = ~screen[i-1];

        delay_ms(1000);

      }

     

 

}

 

Color TV:

#include "sdcard.h"

#include "colortv.h"

 

//#include <malloc.h>

 

#define TV_IMG_WIDTH 48

#define TV_IMG_HEIGHT 36

#define UP 0

#define RIGHT 1

#define DOWN 2

#define LEFT 3

#define maxkeys 16

 

// for keypad

flash unsigned char keytbl[16]={0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb, 0xb7, 0x7e, 0x7d, 0x7b, 0x77};

 

void swapSubImg(int x1, int y1, int x2, int y2, int lenX, int lenY);

void swapSubImg2P(int x1, int y1, int x2, int y2);

 

// Disable register saving, registers critical to the display driver

// Are saved before running any code in C, and then reloaded after doing that.

#pragma savereg-

 

// Do not allow the compiler to assign global variables to the registers

#pragma regalloc-

 

// Slows down input

#define readyCountMax 15

 

// Cursor flash speed

#define cursorCountMax 15

 

#asm

; Port definitions

 

; ***** I/O REGISTER DEFINITIONS *****************************************

; NOTE:

; Definitions marked "MEMORY MAPPED"are extended I/O ports

; and cannot be used with IN/OUT instructions

.equ  PORTA = 0x1b

.equ  DDRA  = 0x1a

.equ  PINA  = 0x19

.equ  PORTB = 0x18

.equ  DDRB  = 0x17

.equ  PINB  = 0x16

.equ  PORTC = 0x15

.equ  DDRC  = 0x14

.equ  PINC  = 0x13

.equ  PORTD = 0x12

.equ  DDRD  = 0x11

.equ  PIND  = 0x10

.equ  TCNT0 = 0x32

.equ  TCNT1L      = 0x2c

.equ  TCNT1H      = 0x2d

 

 

; ***** CPU REGISTER DEFINITIONS *****************************************

.def  XH    = r27

.def  XL    = r26

.def  YH    = r29

.def  YL    = r28

.def  ZH    = r31

.def  ZL    = r30

 

;

; Display Driver Register Definitions

;

 

; registers 0-7 are reserved for pixels.

 

; register 9 holds the last line 272 or 273

.def lastLine = R9

 

; Registers 16 and 19 and up are used for compare checks, therefore, counters need to be

; Above register 16, as 16 is the general purpose register, for moving things

; and loading I/O space registers

 

 

; register 17 is reserved for the pixel counter, it is also used for switching

; the MCUCR when int1 is active

 

.def pixelCount = R17

 

; registers 24 and 25 are reserved for the line counter

 

.def lineCountL = R24

.def lineCountH = R25

 

; register 20 is used for determining if we are on Vertical pulses.

; not needed once in the display code

.def timerReset = R20

 

; register 21 is used for counting how many times a certain line is displayed

; This is compared with lineRepeated, to see if we move to the next line

 

.def lineCopy = R21

                 

; register 26 and 27 will be used for accessing the screen memory, aka register X

            

; Note that the only variables that matter in between the end of the display code

; and the start of the program code is the line counter, and the last line variable.

; Therefore, these must be pushed to the stack before running any program code

; in C.  All other registers are reset at some point before the display code begins.

 

;

;End Display Driver Definitions

;

 

 

 

 

;

; Program Register Definitions

;

 

; register 11 holds the moveCounter, slowing down the polling of the input

.def moveCounter = R11

 

; registers 12 and 13 hold the red and green intensity values

.def redHold = R12

.def greenHold = R13

 

; register 22 is used for telling where the cursor is, screen, R, G, or B

 

.def cursorLocation = R22

 

; register 23 is used for holding what the current pixel is

 

.def holdPixel = R23

 

; register 18 is used for counting how long the cursor has been a certain color

.def cursorCounter = R18

 

 

; register 28 and 29, aka register Y, is used for pointing to where in the screen

; memory the cursor is located

 

 

;

; End Program Register Definitions

;

 

 

 

 

; Variable definitions

 

 

.equ lastPixel = 32          ; The last pixel in a line

 

.equ startLine = 60          ; First line of Display

 

.equ endLine = 240           ; Last line of Display

 

.equ lineRepeated = 4        ; How many times a line has to be repeated

 

.equ lineSubtract = 32       ; When I reach the end of a line, how much I have to subtract

                       ; if the line has to be repeated

 

.equ waitTime = 190          ; Wait time, for back porch to finish

.equ lastLineConst = 272        ; How many lines there are in a screen, during even frames

 

;

; Macros

;

 

; Load screen memory to registers 0-7.  Too slow to be used between each group of pixels

; Use loadPixel to load individual pixels after they have been displayed.

 

; loadScreen MACRO takes 16 cycles to complete, or 1us

 

.MACRO loadScreen

 

      ld r0, X+

      ld r1, X+

      ld r2, X+

      ld r3, X+

      ld r4, X+

      ld r5, X+

      ld r6, X+

      ld r7, X+

     

.ENDMACRO

 

; Load an individual pixel.  This is used for loading a new pixel while the old is

; being displayed.

 

; loadPixel MACRO takes 2 cycles to complete, or 1/8us

 

.MACRO loadPixel

 

      ld @0, X+

 

.ENDMACRO

 

; Blasts out 16 pixels (8 bytes)

.MACRO lineBlast

      pixelBlast r0

      nopDelay

      pixelBlast r1

      nopDelay

      pixelBlast r2

      nopDelay

      pixelBlast r3

      nopDelay

      pixelBlast r4

      nopDelay

      pixelBlast r5

      nopDelay

      pixelBlast r6

      nopDelay

      pixelBlast r7

      nopDelay

.ENDMACRO

 

; Blast out two pixels (one byte) from memory

.MACRO pixelBlast

      out PORTC, @0

      swap @0

        nop

        nop

        nop

        nop

        nop

        nop

    out PORTC, @0

      loadPixel @0

      inc pixelCount

.ENDMACRO

 

.MACRO nopDelay

; Adding or subtracting nops will increase or decrease pixel length

; Based on 16MHz

nop

nop

nop

nop

nop

 

.ENDMACRO

 

.Macro enableSleep

;loads the MCUCR with the sleep enable bit plus what it had before

;that being registers on falling interrupts

ldi r16, 0b10001010

out MCUCR, r16

.ENDMACRO

 

.Macro disableSleep

ldi r16, 0b00001010

out MCUCR, r16

.ENDMACRO

 

;

;End ASM Macros

;

 

#endasm

 

#define PICNUM 1

// global variable

unsigned char execFlag, gameMode, step1, step10;

unsigned int frameCnt;

unsigned int butnum, picnum;

 

UCHAR curpos;

// for length = 12

int position[3][4] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};

int x, y;

UCHAR Flag;

// initialize screen array

unsigned char screen[1536+128]; //= {0xF0, 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0}; //{0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00};

                     

void paintTime(void);

UCHAR pollButtons(void);

void cursorInvert(void);

UCHAR checkwin(void);

void swap();

void readpic(UCHAR Number);

void viewpic();

void shuffle(int side_len);

 

/**********Program Variables**********/

char holdPixel;         // Holds the previous color value

char cursorLocationX;    // Holds the X value of the cursor position

char cursorLocationY;   // Holds the Y value of the cursor position

char redColor;          // Holds the value of red

char greenColor;

char blueColor;

char screenTab;         // Stores where we are on the screen(paint area, R G or B)

char cursorCount;       // stores how many frames the cursor has remained the same color

 

 

 

interrupt [EXT_INT0] void ext_int0(void)

{

//    int i , j;

 

#asm

 ; Interrupt 0 is used for catching the falling pulses from horizontal and Vertical pulses

 ; It will also update the line count.

 

 

        ;Disable sleep

      disableSleep

     

      ;increment line counter

      ADIW lineCountH:lineCountL, 1

 

      ; if lineCount = lastLine, reset counters

      cpi lineCountH, 1

      in r16, SREG

      sbrs r16, 1

      rjmp endSync

      cp lineCountL, lastLine

      breq resetCounters

      rjmp endSync

 

 

endSync:

      ; loop until timer0 says sync pulse has been completed

 

      ; check line number

      rjmp lineCheck

 

resetCounters:

      ldi lineCountL, 1                  ; Reset lineCountL

      ldi lineCountH, 0                  ; Reset lineCountH

 

      ; Change lastLine number, 272 -> 273 or 273 -> 272

      mov r16, lastLine

      cpi r16, low(lastLineConst)

      breq addLine

subtractLine:

      dec lastLine

      rjmp continueReset

addLine:

      inc lastLine

 

     

continueReset:

      ; Reset the pointers to point to the start of screen memory

      ldi XH, HIGH(_screen)

      ldi XL, LOW(_screen)

     

      ldi lineCopy, 1

      rjmp endSync

 

lineCheck:

 

      cpi lineCountL, startLine

      brlo programCode

      cpi lineCountL, endLine + 1

      brsh programCode

      jmp startDisplay

 

;;;;;;;;;PROGRAM CODE;;;;;;;;;;;

 

programCode:

; Save lineCountH and L and save the lastLine variable

; push these to the stack

        push lineCountL

        push lineCountH

        push lastLine

; Do some lineCount checking, to see what line we are on, for running program code

; end line is 240, right now

 

cpi lineCountL, endLine +1

breq programLine1

cpi lineCountL, endLine +2

breq programLine2

cpi lineCountL, endLine +3

breq programLine3

 

; Add more if necessary

 

; if no program code to run, just pop the registers back

jmp next

; Call C program functions

programLine1:

#endasm

  if(execFlag == 0){

    butnum = pollButtons();

    if(butnum>0)

      execFlag = 1;

  }

#asm

jmp next

programLine2:

#endasm 

  if(gameMode == 1) swap();

  else viewpic();

#asm

jmp next

programLine3:

#endasm

  if((execFlag == 0) && (gameMode==1) && curpos == 11 ) checkwin();

 

#asm

next:

cpi lineCountL, endLine +4

breq programLine4

cpi lineCountL, endLine +6

breq programLine5

jmp popRegisters

programLine4:

#endasm

  writeChar(50,28,step10,0x33);

#asm

jmp popRegisters

programLine5:

#endasm

  writeChar(58,28,step1,0x33);

#asm

jmp popRegisters

programLine16:

#endasm

#asm

popRegisters:

        pop lastLine

        pop lineCountH

        pop lineCountL

        jmp endInterrupt

 

;;;;;;;;;;;END PROGRAM CODE;;;;;;;;;;

 

 

;;;;;;;;START DISPLAY DRIVER CODE;;;;;;;

startDisplay:

; At the start of the display, the first 30 lines will not be displayed.

; This means that I have the full 63.5us to use for coding.

; This amounts to 1,016 clock cycles, which should be plenty, if code is optimized

; in assembly

 

preLine:

      ; Load screen memory into the registers

      loadScreen

 

      ;zero timer0

      ldi r16, 0x00

      out TCNT0, r16

 

      ; loop to wait for visible portion of the screen

      waitForVisible:

      in r16, TCNT0

      cpi r16, waitTime

      brlo waitForVisible

 

 

 

      pixelBlasting:

      lineBlast ;1->16

      lineBlast ;16->32

      lineBlast ;32->48

      lineBlast ;48->64

     

 

returnFromInt:

      ; If there is any line cleanup code to do, do it now

 

      ldi r16, 0x00

      out PORTC, r16        ;reset portC to black level

 

      cpi lineCopy, lineRepeated

      brsh nextLineGroup                 ; if displayed the same line lineRepeated times, then nextLineGroup

      SBIW XH:XL, lineSubtract + 8 ; else, reset pointer back to beginning of line memory position

      inc lineCopy                                              ; increment lineCopy

     

      enableSleep

      rjmp endInterrupt

 

; Reset line counter, then return

; Pointer points to next line, so does not have to be changed.

      nextLineGroup:

      SBIW XH:XL, 8

      ldi lineCopy, 1

      enableSleep

      rjmp endInterrupt

 

;;;;;;;;;;END DISPLAY DRIVER CODE;;;;;;;;;

endInterrupt:

#endasm

 

 

}

 

 

 

 

 

interrupt [EXT_INT1] void ext_int1(void)

{

///////////////////////////////////////////////////

//////////Syncing with the Sync Generator//////////

///////////////////////////////////////////////////

 

// Based on the fact that vertical pulses and the equalization pusles

// occur at a rate twice that the horizontal pulses

// Search for when this happens, and then display x lines after that occurs,

// x being when you want to start displaying to the tv, with a certain offset, so we get

// to the top line of the tv screen.

 

#asm

 

; Disable sleep while in interrupt

disableSleep

 

; if timer has not been reset yet, reset timer

cpi timerReset, 0xFF

BREQ checkTime

rjmp exitInt1

         

 

checkTime:

; if low(timer) > 50us

      in r16, TCNT1L

      cpi r16, 100                 ; At 2MHz timer, need 100 cycles to get 50us

      BRLO checkForInit

 

      ; lineCount = 1

      ldi lineCountL, 1

      ldi lineCountH, 0

 

      rjmp exitInt1

 

checkForInit:

      ; if lineCount == 1

      cpi lineCountL, 1

      brne exitInt1

 

     

            ; Load the start of memory into the pointers

            ldi XL, LOW(_screen)

            ldi XH, HIGH(_screen)

 

            ; Set line repeat counter to one

            ldi lineCopy, 1

     

     

            ; Disable int1, enable int0

            ldi r16, 0b01000000

            out GICR, r16

 

            ;reenable sleep

            enableSleep

            reti

 

exitInt1:        

            ; LOW(Timer1) = 0,     Timer Reset

            ldi r16, 0x00

            out TCNT1L, r16

            ;Set timerReset to show that timer has been reset before

            ldi timerReset, 0xFF

 

            ;reenable sleep

            enableSleep

            reti

        #endasm

 

 

}

 

void swap(){   

 

  if(execFlag ==1 && frameCnt < 12) {

 

    y = curpos>>2;

    x = curpos - (y<<2);

 

    switch(butnum){

      case 2:

        if(y<2){

          swapSubImg2P(x*12, y*12+frameCnt, x*12, (y+1)*12+frameCnt);

        }else{

          execFlag = 0 ;

          frameCnt = 0;

        }

        break;

      case 10:

        if(y>0){

          swapSubImg2P(x*12, (y-1)*12+frameCnt, x*12, y*12+frameCnt);

        }else{

          execFlag = 0 ;

          frameCnt = 0;

        }

        break;

      case 5:

        if(x<3){

          swapSubImg2P(x*12, y*12+frameCnt, (x+1)*12, y*12+frameCnt);

        }else{

          execFlag = 0 ;

          frameCnt = 0;

        }

        break;

      case 7:

        if(x>0){

          swapSubImg2P(x*12, y*12+frameCnt, (x-1)*12, y*12+frameCnt);

        }else{

          execFlag = 0 ;

          frameCnt = 0;

        }

        break;

 

      case 4:

        if(picnum >0){

          picnum--;

          readpic(picnum);

          gameMode = 0;

        }

        execFlag = 0 ;

        frameCnt = 0;

        break;

      case 12:

        if(picnum <PICNUM){

          picnum++;

          readpic(picnum);

          gameMode = 0;

        }

        execFlag = 0 ;

        frameCnt = 0;

        break;

     }

  }

 

  if(execFlag == 1 && frameCnt < 12)

    frameCnt++;

  if(frameCnt == 12) {

    execFlag = 0;

    frameCnt=0;

    switch(butnum) {

      case 2:

        if(y<2){

          curpos = curpos + 4;

          step10 = step10-'0';

          step1 = step1 - '0';

          step10+=(step1+1)/10;

          step1 = (step1+1)%10;

          step10 = step10+'0';

          step1 = step1 + '0';

        }

        break;

      case 10:

        if(y>0){

          curpos = curpos - 4;

          step10 = step10-'0';

          step1 = step1 - '0';

          step10+=(step1+1)/10;

          step1 = (step1+1)%10;

          step10 = step10+'0';

          step1 = step1 + '0';

 

        }

        break;

      case 5:

        if(x<3){

          curpos = curpos + 1;

          step10 = step10-'0';

          step1 = step1 - '0';

          step10+=(step1+1)/10;

          step1 = (step1+1)%10;

          step10 = step10+'0';

          step1 = step1 + '0';

 

        }

        break;

      case 7:

        if(x>0){

          curpos = curpos - 1;

          step10 = step10-'0';

          step1 = step1 - '0';

          step10+=(step1+1)/10;

          step1 = (step1+1)%10;

          step10 = step10+'0';

          step1 = step1 + '0';

        }

    }

 

  }

}

 

void viewpic(){

 

    switch(butnum){

      case 8:

        #asm

          cli

        #endasm

        shuffle(2);

        #asm

          sei

        #endasm

        gameMode = 1;

        execFlag = 0 ;

        frameCnt = 0;

        break;

      case 4:

        if(picnum >0) {

          picnum--;

          readpic(picnum);

          gameMode = 0;

        }

        execFlag = 0 ;

        frameCnt = 0;

        break;

      case 12:

        if(picnum <PICNUM){

          picnum++;

          readpic(picnum);

          gameMode = 0;

        }

        execFlag = 0 ;

        frameCnt = 0;

        break;

    }

   execFlag = 0;

}

 

void getCoord(int num, int nX, int* x, int* y) {

      *x = num % nX;

      *y = num / nX;

}

 

UCHAR checkwin(){

  UCHAR i,x,y;

  for(i=0;i<12;i++){

    y = i/3;

    x = i%4;

    if(position[x][y] != i)

      return 0;

  }

  return 1;

 

}

 

void shuffle(int side_len) {

  UINT i,j,temp;

  UCHAR x1,x2,y1,y2;

 

  for(i=0;i<2;i++){

    do{

    x1 = rand()%4;

    x2 = rand()%4;

    y1 = rand()%3;

    y2 = rand()%3;

    }while(((y1*4+x1)==11) || (y2*4+x2)==11);

    for(j=0;j<12;j++)

      swapSubImg2P(x1*12, y1*12+j, x2*12, y2*12+j);

     

    temp = position[x1][y1];

    position[x1][y1] = position[x2][y2];

    position[x2][y2] = temp;

  }

  for(j=24;j<36;j++)

        for(i=18;i<24;i++)

          screen[(j<<5)+i]=0x00;  

  curpos = 11;

  step1 = '0';

  step10 = '0';

 

 

}

 

void swapSubImg2P(int x1, int y1, int x2, int y2) {

 UCHAR temp, i;             

 UINT loc1, loc2;

 x1 = x1>>1;

 x2 = x2>>1;

 y1 = y1<<5;

 y2 = y2<<5;

 

 loc1 = x1+y1;

 loc2 = x2+y2;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

 loc1 = x1+y1+1;

 loc2 = x2+y2+1;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

 loc1 = x1+y1+2;

 loc2 = x2+y2+2;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

 loc1 = x1+y1+3;

 loc2 = x2+y2+3;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

 loc1 = x1+y1+4;

 loc2 = x2+y2+4;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

 loc1 = x1+y1+5;

 loc2 = x2+y2+5;

 temp = screen[loc1];

 screen[loc1] = screen[loc2];

 screen[loc2] = temp;

 

}

 

void swapSubImg(int x1, int y1, int x2, int y2, int lenX, int lenY) {

    int i , j;

      UINT sx1, sx2, sLenX, loc1, loc2, loc_x1, loc_x2, loc_y1, loc_y2;

      UCHAR temp;

      sx1 = x1 >> 1;

      sx2 = x2 >> 1;

    sLenX = lenX >> 1;

      for( j = lenY-1 ; j >= 0 ; j-- ) {

          loc_y1 = (y1+j)<<5;

          loc_y2 = (y2+j)<<5;

     for( i = sLenX-1 ; i >= 0; i-- ) {

         loc_x1 = sx1 + i;

         loc1 = loc_x1 + loc_y1;

         loc_x2 = sx2 + i;

         loc2 = loc_x2 + loc_y2;

                  temp = screen[loc1];

                  screen[loc1] = screen[loc2];

                  screen[loc2] = temp;

            }

      }

}  

 

 

// Initialization code

void initialization(void)

{    

        /*****Port Initialization*****/

  UINT i, j, r, c;

  int newy, newx, newpos;

  int subImgLen;

      // PortA will be used for input, from switches

      // Note: A 1 on a port bit corresponds to an unpressed switch

 

        DDRA = 0x00;

     

      // PortB will be used to display out to the LEDs, for debugging purposes

      // Note: A 0 on a port bit corresponds to a lit LED

        DDRB = 0xFF;

 

            // Start with LEDs half on, half off

            PORTB = 0xF0;

 

      // PortC will be used to output to the TV

      DDRC = 0xFF;

                // Init at black level

            PORTC = 0x00;

 

      // PortD will be used to take in the sync pulses, the external interrupt on bit2 is active

      // One interrupt will be for line counting, the second interrupt will be for initial sync with the generator

      DDRD = 0x00;

 

 

        /*****Interrupts and Timers*****/

 

      // Disable interrupts on timers

      TIMSK = 0;

     

      // Set Timer0 Control Register, no prescaler

      TCCR0 = 0x01;

 

      //Turn off PWM and other in Timer1 Control RegisterA

      TCCR1A = 0x00;

     

      // Set Timer1 Control RegisterB, at clock speed/8 = 2MHz

      TCCR1B = 0x02;

 

      // Set interrupts 0 and 1 to register on falling edge (horizontal sync is a falling edge, followed by a rising edge)

      // Idle sleep mode also set

      MCUCR = 0b00001010;

 

      // Enable external interrupt 1 to seach for sync pulses.

        GICR = 0b10000000; 

 

    execFlag = 0;

    frameCnt = 0;

       

        /*****Variable Initialization*****/

      //////////////////////////////////////////////////  

      //////////Display Driver Initializations//////////

      //////////////////////////////////////////////////

      #asm

      ; Initialize line counter at 0

      ; Int1 will set line count to 1, when it finishes

      ldi lineCountL, 0

      ldi lineCountH, 0

 

      ; Set the timerReset to 0, to show that timer has not been reset yet

      ldi timerReset, 0x00

 

      ; Set the last line variable to whatever the last line starts at

      ldi r16, low(lastLineConst)

      mov lastLine, r16

     

      ; Initialize the lineCopy variable at 1

      ldi lineCopy, 1

        #endasm

       

      ///////////////////////////////////////////

      //////////Program Initializations//////////

      ///////////////////////////////////////////

 

    curpos = 11;

    x = 3;

    y = 2;

    step1 = '0';

    step10 = '0';

 

}

 

void readpic(UCHAR Number){

  int i,j;

  #asm

    cli

  #endasm

       

        MmcInit();

        set_blocksize(512);

        mmc_read_sector(Number*1024,&screen[1152],512);

        for(i=0;i<21;i++){

          for(j=0;j<24;j++){

            screen[i*32+j] = screen[1152+j+i*24];

          }

        }

        for(i=0;i<8;i++) screen[21*32+i] = screen[1152+504+i];

        mmc_read_sector((Number*1024+512),&screen[1152],512);

        for(i=0;i<16;i++) screen[21*32+i+8] = screen[1152+i];

        for(i=0;i<14;i++){

          for(j=0;j<24;j++){

            screen[(i+22)*32+j] = screen[1168+j+i*24];

          }

        }

        for(i=0;i<512;i++)

          screen[i+1152]=0;

        step1 = '0';

        step10 = '0';

 #asm

 sei

 #endasm

}

 

 

void writeChar(char x, char y, char letter, char color)

{

  unsigned int i, j, z, location;

 

  x= x/2;

  letter = letter - '0';

  if(letter>10) letter = letter - 7;

  location = ((UINT)letter) * 21;

  x=x+3;

  y=y+7;

  z = 0;

  for(j=y-7;j<y;j++){

    for(i=x-3;i<x;i++){

      screen[i+j*32]=(characters[location+z++] & color);

    }

  }

 

/*for(i=0;i<3;i++){

    for(j=0;j<7;j++){

      screen[(27+j)*32+i+25] = charac[j*3+i];

    }

  }

*/

}

void main(void)

{                 

      int i,j; 

 

       picnum = 0;

       //for(i=0;i<512;i++) {

        //  PORTA=~(screen[i]);

        //  delay_ms(1000);

        //}

       

        //DDRA = 0xff;

        //shuffle(12);      

 

        initialization();

 

        DDRA = 0xff;

        if(MmcInit()==0) PORTA=0x0f;

        delay_ms(500);

        set_blocksize(512);

        mmc_read_sector(0,&screen[1152],512);

 

        for(i=0;i<21;i++){

          for(j=0;j<24;j++){

            screen[i*32+j] = screen[1152+j+i*24];

          }

        }

        

        for(i=0;i<8;i++) screen[21*32+i] = screen[1152+504+i];

        mmc_read_sector(512,&screen[1152],512);

       

        for(i=0;i<16;i++) screen[21*32+i+8] = screen[1152+i];

        for(i=0;i<14;i++){

          for(j=0;j<24;j++){

            screen[(i+22)*32+j] = screen[1168+j+i*24];

          }

        }

        for(i=0;i<512;i++)

          screen[i+1152]=0;

        PORTA = 0xf0;

        delay_ms(500);

        writeChar(50,4,'D',0xFF);

       

        writeChar(58,4,'O',0xbb);

 

        writeChar(50,12,'I',0xFF);

        writeChar(58,12,'T',0xaa);

 

 

//        readpic(1);

 

        // Turn on interrupts

        #asm

                sei

        #endasm

        // Sleep until interrupt, when returning from interrupt, sleep    

 

        while(1)

        {

          #asm("sleep");

        }

  

}                                                         

 

 

/*** Program Functions ***/

 

UCHAR pollButtons(void)

{      

        unsigned char butnum, key;

        char ready;

        char readyCount;

        //if (ready)

        //{

            //get lower nibble

 

              DDRA = 0x0f;

              PORTA = 0xf0;

            delay_us(2);

              key = PINA;

        

              //get upper nibble

              DDRA = 0xf0;

              PORTA = 0x0f;

              delay_us(2);

              key = key | PINA;

        

              //find matching keycode in keytbl

              if (key != 0xff){  

                  for (butnum=0; butnum<maxkeys; butnum++){   

                      if (keytbl[butnum]==key)  break;  

                }

                    if (butnum==maxkeys) butnum=0;

                    else butnum++;    //adjust by one to make range 1-16

                } 

              else butnum = 0;

 

            return butnum;

}

 

 

SD card:               

               

// SPI information obtained from SanDisk's SD card manual

// http://www.sandisk.com/pdf/oem/ProdManualSDCardv1.9.pdf

 

/*

    Portions of this code were adapted and used from

    Radig Ulrich <mail@ulrichradig.de>

*/

#include "sdcard.h"

#define TRUE  (0x1)

#define FALSE (0x0)

 

#define R1_IN_IDLE_STATE    (0x1)   // The card is in idle state and running initializing process.

#define R1_ERASE_RESET      (0x2)   // An erase sequence was cleared before executing because of an out of erase sequence command was received.

#define R1_ILLEGAL_COMMAND  (0x4)   // An illegal command code was detected

#define R1_COM_CRC_ERROR    (0x8)   // The CRC check of the last command failed.

#define R1_ERASE_SEQ_ERROR  (0x10)  // An error in the sequence of erase commands occured.

#define R1_ADDRESS_ERROR    (0x20)  // A misaligned address, which did not match the block length was used in the command.

#define R1_PARAMETER        (0x40)  // The command's argument (e.g. address, block length) was out of the allowed range for this card.

 

#define READ_START_BLOCK            (0b11111110)

#define WRITE_SINGLE_START_BLOCK    (0b11111110)

#define WRITE_MULTIPLE_START_BLOCK  (0b11111100)

#define WRITE_MULTIPLE_STOP_TRAN    (0b11111101)

#define MMC_DR_MASK                 0x1F

#define MMC_DR_ACCEPT               0x05

 

#define MSTR                4

#define SPR0                0

#define SPR1                1

#define SPE                 6

#define SPI2X               0

#define SPIF                7

 

#define MMC_Write           PORTB

#define MMC_Read            PINB

#define MMC_Direction_REG   DDRB

 

#define SPI_DI              6

#define SPI_DO              5

#define SPI_Clock           7

#define MMC_Chip_Select     0

#define SPI_SS              4

 

#define nop()               #asm("nop")

 

//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)

#define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);

 

//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)

#define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select);

UCHAR set_blocksize (UINT Blocksize);

UCHAR Write_Command_MMC(UCHAR *CMD);

 

inline void Write_Byte_MMC(UCHAR Byte)

{

    SPDR = Byte;

    while(!(SPSR & (1<<SPIF)));

}  

inline UCHAR Read_Byte_MMC(void)

{

    UCHAR Byte;

    SPDR = 0xff;

 

    while(!(SPSR & (1<<SPIF)));

 

    Byte = SPDR;   

    return (Byte);

}

 

UCHAR Write_Command_MMC(UCHAR *CMD)

{

    UCHAR a;

    UCHAR tmp = 0xff;

    UCHAR Timeout = 0;

 

    // Raise chip select

    MMC_Disable();

 

    // Send an 8 bit pulse

    Write_Byte_MMC(0xFF);

 

    // Lower chip select

    MMC_Enable();

 

    // Send the 6 byte command

    for (a = 0;a<0x06;a++)

    {

        Write_Byte_MMC(*CMD++);

    }

 

    // Wait for the response

    while (tmp == 0xff)

    {

        tmp = Read_Byte_MMC();

        if (Timeout++ > 100)

        {

            break;

        }

    }

    // for some reason we need to delay here

    delay_ms(1);

 

    return(tmp);

}

 

UCHAR MmcInit()

{

    UCHAR a,b, retry;

    UCHAR CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};

 

    // Set certain pins to inputs and others to outputs

    // Only SPI_DI (data in) is an input

    MMC_Direction_REG &=~(1<<SPI_DI);

    MMC_Direction_REG |= (1<<SPI_Clock);

    MMC_Direction_REG |= (1<<SPI_DO);

    MMC_Direction_REG |= (1<<MMC_Chip_Select);

    MMC_Direction_REG |= (1<<SPI_SS);

    MMC_Write |= (1<<MMC_Chip_Select);

 

    // We need to wait for the MMC_Direction_REG to be ready

    for(a=0;a<200;a++)

    {

        nop();

    };

 

    // Enable SPI in Master Mode with IDLE low and clock at 16E6/128

    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);

    SPSR = (0<<SPI2X);

 

    // We need to give the card about a hundred cycles to load

    for (b = 0; b < 0x0f; ++b)

    {

        Write_Byte_MMC(0xff);

    }

   

    // Send the initialization commands to the card

    retry = 0;

 

    // Note, many examples check for (Write_Command_MMC(CMD) == R1_IN_IDLE_STATE)

    // However, with our setup the card was in IDLE state and returning another command

    while((Write_Command_MMC(CMD) & R1_IN_IDLE_STATE) == 0)

    {

        // fail and return

        if (retry++ > 50)

        {

            return 1;

        }

    }

 

    // Send the 2nd command

    retry = 0;

    CMD[0] = 0x41;

    CMD[5] = 0xFF;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 2;

        }

    }

/*

    retry = 0;

    CMD[0] = 0x50;

    CMD[5] = 0xFF;

    CMD[3] = 0x02;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 2;

        }

    }

*/

    // Set the SPI bus to full speed

    SPCR = SPCR|(0<<SPR0)|(0<<SPR1);

    SPSR = SPSR|(1<<SPI2X);

   

    // Raise Chip Select

    MMC_Disable();

   

    return 0;

}

 

UCHAR mmc_write_sector (unsigned long addr,UCHAR *Buffer,UINT Blocksize)

{

    UCHAR tmp;

    UINT a;

 

    // Command to write a block to the memory card

    UCHAR CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};

 

    // Encode the address to a 32-bit address

    // Ignore the bottom byte of the address as we give the address of the sector

    CMD[1] = ((addr & 0xFF000000) >> 24);

    CMD[2] = ((addr & 0x00FF0000) >> 16);

    CMD[3] = ((addr & 0x0000FF00) >> 8);

    CMD[4] =   addr & 0x000000FF;

    // Send the write command

    tmp = Write_Command_MMC (CMD);

    if (tmp != 0)

    {

        return(tmp);

    }

            

    // Wait a little bit

    for (a = 0; a < 100; ++a)

    {

        Read_Byte_MMC();

    }

 

    // Send the start byte

    Write_Byte_MMC(0xFE);  

 

    // Send all bytes in the buffer

    for (a = 0; a < Blocksize; ++a)

    {

        Write_Byte_MMC(*Buffer++);

    }

 

    // Write CRC byte

    Write_Byte_MMC(0xFF);

    Write_Byte_MMC(0xFF);

 

    // Wait for the write to complete

    while (Read_Byte_MMC() != 0xff);

 

    // Set MMC_Chip_Select to high

    MMC_Disable();

 

    return(0);

}

 

UCHAR MMC_Read_Block(UCHAR *CMD,UCHAR *Buffer,UINT Bytes)

{  

    UINT a;

    UCHAR temp;

 

    // Send the read command

    if (temp = Write_Command_MMC(CMD) != 0)

    {

        return;

    }

           

    // Send the start byte

    while (Read_Byte_MMC() != 0xfe);

 

    // Read off all the bytes in the block

    for (a = 0; a < Bytes; ++a)

    {

        PORTA=0xff;

        *Buffer++ = Read_Byte_MMC();

        PORTA=0x00;

    }

 

    // Read CRC byte

    Read_Byte_MMC();

    Read_Byte_MMC();

 

    // Set MMC_Chip_Select to high

    MMC_Disable();

 

    return;

}

UCHAR set_blocksize (UINT Blocksize)

{  

    char retry;

    // Command to set blocksize

    UCHAR CMD[] = {0x50,0x00,0x00,0x00,0x00,0xFF};

    CMD[1] = ((Blocksize & 0xFF000000) >> 24);

    CMD[2] = ((Blocksize & 0x00FF0000) >> 16);

    CMD[3] = ((Blocksize & 0x0000FF00) >> 8);

    CMD[4] =   Blocksize & 0x000000FF;

    retry = 0;

    while( Write_Command_MMC (CMD) != 0)

    {

        if (retry++ > 50)

        {

            return 1;

        }

    }

    MMC_Disable();

    return 0;

}

UCHAR mmc_read_sector (unsigned long addr, UCHAR *Buffer, UINT Blocksize)

{  

    // Command to read a 512-byte sector

    UCHAR CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};

 

    // Encode the address to a 32-bit address

    // Ignore the bottom byte of the address as we give the address of the sector

     

    //addr = addr << 9; //addr = addr * 512

 

    CMD[1] = ((addr & 0xFF000000) >> 24);

    CMD[2] = ((addr & 0x00FF0000) >> 16);

    CMD[3] = ((addr & 0x0000FF00) >> 8);

    CMD[4] =   addr & 0x000000FF;

 

    MMC_Read_Block(CMD,Buffer,Blocksize);

 

    return(0);

}