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);
}