Game of Life on Color LCD

I did this a while ago and have stopped working on it as I have lost interest in the LCD as it is kind of slow.

The LCD I used can be found here:
http://www.seeedstudio.com/depot/320240-graphic-lcd-w-touch-screen-and-hw-accel-p-147.html?cPath=8

I got most of the hardware functions working; I never did try to get the sprites working. The library I created is in the next two posts.

Anyway here is my implementation of the game of life on a 320x240 color lcd.

there are 40x30 cells as the only way I could get a reasonable amount of speed out of the LCD was to feed it the data as special characters that are either a blank character of solid block character.

Anyway here is the life sketch:

#include <TCB8000C.h>
#include <stdlib.h>

#define ALIVE 1
#define DEAD 0

#define bheight 30
#define bwidth 40 // must be devisable by 8

#define ALIVEch 219
#define DEADch 255

char cdisplay = 0;
char cbuff = 1;

unsigned int generation = 0;
unsigned int buffer[16];
int count = 0;
unsigned char board[2][bheight][bwidth/8] = {
//board 0
//0         8         16        24        32
{{B00000000,B00000000,B00000000,B00000000,B00000000}, //0
 {B00000000,B00000000,B00000000,B01000000,B00000000}, //1
 {B00000000,B00000000,B00000001,B01000000,B00000000}, //2
 {B00000000,B00000110,B00000110,B00000000,B00011000}, //3
 {B00000000,B00001000,B10000110,B00000000,B00011000}, //4
 {B01100000,B00010000,B01000110,B00000000,B00000000}, //5
 {B01100000,B00010001,B01100001,B01000000,B00000000}, //6
 {B00000000,B00010000,B01000000,B01000000,B00000000}, //7
 {B00000000,B00001000,B10000000,B00000000,B00000000}, //8
 {B00000000,B00000110,B00000000,B00000000,B00000000}, //9
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //10
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //11
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //12
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //13
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //14
 {B00001110,B00111000,B00000000,B00000000,B00000000}, //15
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //16
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //17
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //18
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //19
 {B00001110,B00111000,B00000000,B00000000,B00000000}, //20
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //21
 {B00001110,B00111000,B00000000,B00000000,B00000000}, //22
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //23
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //24
 {B00100001,B01000010,B00000000,B00000000,B00000000}, //25
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //26
 {B00001110,B00111000,B00000000,B00000000,B00000000}, //27
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //28
 {B00000000,B00000000,B00000000,B00000000,B00000000}}, //29
//board 1
//0         8         16        24        32
{{B00000000,B00000000,B00000000,B00000000,B00000000}, //0
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //1
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //2
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //3
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //4
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //5
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //6
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //7
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //8
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //9
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //10
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //11
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //12
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //13
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //14
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //15
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //16
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //17
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //18
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //19
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //20
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //21
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //22
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //23
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //24
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //25
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //26
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //27
 {B00000000,B00000000,B00000000,B00000000,B00000000}, //28
 {B00000000,B00000000,B00000000,B00000000,B00000000}} //29
};

// drawing functions:

void display();
void printStatus();

// life game functions:
char isAlive(int x, int y);
void update();
char neighbors(int x, int y);
void setCell(int x, int y, int b, char status);

void setup() {
      init_lcd();
}

void loop() {
      display();
      printStatus();
      update();
}

char isAlive(int x, int y) {
      int xindex = x >> 3; // shift operation is is the same as (x-1)/8
      int bit = x & B00000111; // same as
      char mask = B10000000 >> bit;
      
      return board[cdisplay][y][xindex] & mask;
}

void update() {
      char count;
      for (int y = 0; y < bheight; y++) {
            for (int x = 0; x < bwidth; x++) {
                  count = neighbors(x,y);

                  if ( count == 3 )
                        setCell(x,y,cbuff,ALIVE);
                  else if ( isAlive(x,y) && count == 2 )
                        setCell(x,y,cbuff,ALIVE);
                  else
                        setCell(x,y,cbuff,DEAD);
            }
      }
      if ( cdisplay == 1) {
            cdisplay = 0;
            cbuff = 1;
      }
      else {
            cdisplay = 1;
            cbuff = 0;
      }
      generation++;
}

char neighbors( int x, int y ) {
      char count = 0;
      if ( x > 0 && x < bwidth-1 && y > 0 && y < bheight-1 ) {
            // 3 above
            if ( isAlive(x-1,y-1) ) count++;
            if ( isAlive(x,y-1) ) count++;
            if ( isAlive(x+1,y-1) ) count++;
            
            // 2 to each side
            if ( isAlive(x-1,y) ) count++;
            if ( isAlive(x+1,y) ) count++;
            
            // 3 below
            if ( isAlive(x-1,y+1) ) count++;
            if ( isAlive(x,y+1) ) count++;
            if ( isAlive(x+1,y+1) ) count++;
      }
      else if ( x == 0 && y == 0 ) {
            if ( isAlive(x+1,y) ) count++;
            if ( isAlive(x,y+1) ) count++;
            if ( isAlive(x+1,y+1) ) count++;
      }
      else if ( x == bwidth-1 && y == bheight-1 ) {
            if ( isAlive(x-1,y-1) ) count++;
            if ( isAlive(x,y-1) ) count++;
            if ( isAlive(x-1,y) ) count++;
      }
      else if ( x == 0 ) {
            if ( isAlive(x,y-1) ) count++;
            if ( isAlive(x+1,y-1) ) count++;
            if ( isAlive(x+1,y) ) count++;
            if ( isAlive(x,y+1) ) count++;
            if ( isAlive(x+1,y+1) ) count++;
      }
      else if ( x == bwidth-1 ) {
            if ( isAlive(x-1,y-1) ) count++;
            if ( isAlive(x,y-1) ) count++;
            if ( isAlive(x-1,y) ) count++;
            if ( isAlive(x-1,y+1) ) count++;
            if ( isAlive(x,y+1) ) count++;
      }
      else if ( y == 0 ) {
            if ( isAlive(x-1,y) ) count++;
            if ( isAlive(x+1,y) ) count++;
            if ( isAlive(x-1,y+1) ) count++;
            if ( isAlive(x,y+1) ) count++;
            if ( isAlive(x+1,y+1) ) count++;
      }
      else {
            if ( isAlive(x-1,y-1) ) count++;
            if ( isAlive(x,y-1) ) count++;
            if ( isAlive(x+1,y-1) ) count++;
            if ( isAlive(x-1,y) ) count++;
            if ( isAlive(x+1,y) ) count++;
      }
      return count;
}

void setCell(int x, int y, int b, char status) {
      int xindex = x >> 3; // shift operation is is the same as (x-1)/8
      int bit = x & B00000111; // same as
      char mask = B10000000 >> bit;
      
      if (status)
            board[b][y][xindex] = board[b][y][xindex] | mask;
      else
            board[b][y][xindex] = board[b][y][xindex] & ~mask;
}

void display() {
      char string_line[41];
      
      set_color_fg_font(RED);
      set_color_bg(BLACK);
      string_line[40] = '\0';
      
      for (int y = 0; y < bheight; y++) {
            for (int x = 0; x < bwidth; x++) {
                  if( isAlive(x,y) )
                        string_line[x] = ALIVEch;
                  else
                        string_line[x] = DEADch;
            }
            print_string(0,y*8,(unsigned char *)string_line, 's');
      }
}

void printStatus() {
      char buf[6];
      set_color_fg(WHITE);
      set_color_bg(BLACK);
      print_string(0,232,(unsigned char*)"Generation:",'s');
      itoa(generation, buf, 10);
      print_string(96,232,(unsigned char*)buf,'s');
}

the header file for the library I created "TCB8000C.h":

#ifndef TCB8000C_H_
#define TCB8000C_H_

//port definitions

#define WAIT    0x08
#define A1_1  PORTC |= 0x01
#define A1_0  PORTC &= ~0x01
#define CS_1  PORTC |= 0x02
#define CS_0  PORTC &= ~0x02
#define RES_1 PORTC |= 0x04
#define RES_0 PORTC &= ~0x04
#define RD_1  PORTC |= 0x10
#define RD_0  PORTC &= ~0x10
#define WR0_1 PORTC |= 0x20
#define WR0_0 PORTC &= ~0x20

// data bus is defined as
// high 6 bits are on PORTD.2 through PORTD.7
// low 2 bits are on PORTB.0 and PORTB.1

// color definitions
#define      RED            0xf800
#define      GREEN      0x07e0
#define      BLUE      0x001f
#define      YELLOW      0xffe0
#define      CYAN      0x07ff
#define      MAGENTA      0xf81f
#define      BLACK      0x0000
#define      WHITE      0xffff
#define GRAY    0xdefb


//-----------------------------------------------------------------------------
// Communication Functions
//-----------------------------------------------------------------------------

// put the 8 bit word onto the bus
void setLCDBUS(unsigned char command);

//send a byte to the lcd
void send_byte ( unsigned char command );

//close the byte stream of commands
void close_byte();

//send a full command package
void send_package(unsigned char *package);


//------------------------------------------------------------------------------
// Color Set Functions
//------------------------------------------------------------------------------

//set the foreground color of shapes (the color of the shape
void set_color_fg(unsigned int color);

// set the font foreground color (the color of the text)
// setting the regular fg will also set the fg for the font.
void set_color_fg_font(unsigned int color);

// set the font background color (the color backdrop behind the text)
void set_color_bg(unsigned int color);


//------------------------------------------------------------------------------
// Drawing functions
//------------------------------------------------------------------------------

//set a pixel
void set_pixel(unsigned int X, unsigned int Y);

//Draw a line
void draw_line(unsigned int x1, unsigned int y1, unsigned int x2,
                     unsigned int y2);

//Draw an empty rectangle
void draw_rect(unsigned int x1, unsigned int y1,
                     unsigned int x2, unsigned int y2);

//draw an empty circle
void draw_circle(unsigned int X, unsigned int Y, unsigned char R);

// fill a rectangle
void fill_rect(unsigned int x1, unsigned int y1,
                     unsigned int x2, unsigned int y2);

//draw a filled circle
void fill_circle(unsigned int X, unsigned int Y, unsigned char R);

//-----------------------------------
// String Routine
// max 64 byte in string
// size s = 8x8 font
//      m = 16x16 GB2312-80 (External ROM)
//      b = 16x16 BIG5 (External ROM)
//-----------------------------------
void print_string(unsigned int X, unsigned int Y,
                          unsigned char *pstr, unsigned char size);

// print a character at X,Y
void printchar(unsigned int X, unsigned int Y, unsigned char character);

//-----------------------------------
// Prints a 16-bit bitmap
// x,y = coordinates of the top left corner of the bmp
// w = the width in pixels of the bmp
// h = the height in pixels of the bmp
//-----------------------------------
void show_bmp( unsigned int x, unsigned int y,
                     unsigned int w, unsigned int h, unsigned int * bmp);


//-----------------------------------
// Initilizes required values for a full screen direct draw
// This is used when a full frame is to be written directy to the
// the LCD. It is faster then primative shape drawing.
//-----------------------------------
void fdd_init(unsigned int line);


//----------------------------------
// draw 16 pixels to the screen as a package
// pkg = the 16 pixels to be drawn, anything beyond the 16 will be ignored.
//
// fdd_init() MUST be called first
//----------------------------------
void fdd_sendpackage(unsigned int *pkg);


//-----------------------------------------------------------------------------
// initialization function
//-----------------------------------------------------------------------------
void init_lcd();

#endif /* TCB8000_H_ */

And the cpp file for the library "TCB8000C.cpp"

#include "TCB8000C.h"
#include <avr/io.h>
#include <wiring.h>
#include <binary.h>

#define us_delay 0
#define us_scale 750
#define shape_delay 3      //spec: 20ms
#define package_delay 2 //spec: 2ms
#define LINEDELAY 1 // spec: 5

//----------------------------------------------------------------------------------
// Communication Functions
//----------------------------------------------------------------------------------

void setLCDBUS(unsigned char command) {
      PORTD &= ~0xFC;
      PORTB &= ~0x03;
      PORTD |= (command & 0xFC);
      PORTB |= (command & 0x03);
}


//send a byte to the lcd
void send_byte ( unsigned char command ) {
      A1_0;
      setLCDBUS(command);
      CS_0;
      WR0_0;
      WR0_1;
      CS_1;
}// end send_byte


//close the byte stream of commands
void close_byte() {
      A1_1;
      setLCDBUS(0x01);
      CS_0;
      WR0_0;
      WR0_1;
      CS_1;
}// end close_byte


//send a full command package
void send_package(unsigned char *package) {
      unsigned char i;
      for (i = *package; i ; i--)
      send_byte( *(++package));
      close_byte();
#if us_delay
      delayMicroseconds(package_delay*us_scale);
#else
      delay(package_delay);
#endif
}// end send_package


//----------------------------------------------------------------------------------
// Color Set Functions
//----------------------------------------------------------------------------------

//set the forground color of shapes (the color of the shape
void set_color_fg(unsigned int color) {
      unsigned char Buffer[4];

      Buffer[0]=3;
      Buffer[1]=0x20;
      Buffer[2]=color;
      Buffer[3]=color>>8;
      send_package(Buffer);
}// end SetFgColor


// set the font forground color (the color of the text)
// setting the regular fg will also set the fg for the font.
void set_color_fg_font(unsigned int color) {
      unsigned char Buffer[4];

      Buffer[0]=3;
      Buffer[1]=0x14;
      Buffer[2]=color;
      Buffer[3]=color>>8;
      send_package(Buffer);
}// end SetFontFgColor


// set the font background color (the color backdrop behind the text)
void set_color_bg(unsigned int color) {
      unsigned char Buffer[4];

      Buffer[0]=3;
      Buffer[1]=0x15;
      Buffer[2]=color;
      Buffer[3]=color>>8;
      send_package(Buffer);
}// end SetFontBgColor


//----------------------------------------------------------------------------------
// Drawing functions
//----------------------------------------------------------------------------------

//set a pixel
void set_pixel(unsigned int X, unsigned int Y) {
      unsigned char Buffer[6];

      Buffer[0]=5;
      Buffer[1]=0x23;
      Buffer[2]=X;
      Buffer[3]=X>>8;
      Buffer[4]=Y;
      Buffer[5]=Y>>8;
      send_package(Buffer);
}// end of set_pixel


//Draw a line
void draw_line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
      unsigned char Buffer[10];

      Buffer[0]=9;
      Buffer[1]=0x24;
      Buffer[2]=x1;
      Buffer[3]=x1>>8;
      Buffer[4]=y1;
      Buffer[5]=y1>>8;
      Buffer[6]=x2;
      Buffer[7]=x2>>8;
      Buffer[8]=y2;
      Buffer[9]=y2>>8;
      send_package(Buffer);
#if us_delay
      delayMicroseconds(5*us_scale);
#else
      delay(LINEDELAY);
#endif
}//end draw_line


//Draw an empty rectangle
void draw_rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
      unsigned char Buffer[10];

      Buffer[0]=9;
      Buffer[1]=0x26;
      Buffer[2]=x1;
      Buffer[3]=x1>>8;
      Buffer[4]=y1;
      Buffer[5]=y1>>8;
      Buffer[6]=x2;
      Buffer[7]=x2>>8;
      Buffer[8]=y2;
      Buffer[9]=y2>>8;
      send_package(Buffer);
#if us_delay
      delayMicroseconds(shape_delay*us_scale);
#else
      delay(shape_delay);
#endif
}//end draw_rect


//draw an empty circle
void draw_circle(unsigned int X, unsigned int Y, unsigned char R) {
      unsigned char Buffer[7];

      Buffer[0]=6;
      Buffer[1]=0x28;
      Buffer[2]=X;
      Buffer[3]=X>>8;
      Buffer[4]=Y;
      Buffer[5]=Y>>8;
      Buffer[6]=R;
      send_package(Buffer);
#if us_delay
      delayMicroseconds(shape_delay*us_scale);
#else
      delay(shape_delay);
#endif
}//end draw_circle


// fill a rectangle
void fill_rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
      unsigned char Buffer[10];

      Buffer[0]=9;
      Buffer[1]=0x27;
      Buffer[2]=x1;
      Buffer[3]=x1>>8;
      Buffer[4]=y1;
      Buffer[5]=y1>>8;
      Buffer[6]=x2;
      Buffer[7]=x2>>8;
      Buffer[8]=y2;
      Buffer[9]=y2>>8;
      send_package(Buffer);
#if us_delay
      delayMicroseconds(shape_delay*us_scale);
#else
      delay(shape_delay);
#endif
}// end Fill_Rect


//draw a filled circle
void fill_circle(unsigned int X, unsigned int Y, unsigned char R) {
      unsigned char Buffer[7];

      Buffer[0]=6;
      Buffer[1]=0x29;
      Buffer[2]=X;
      Buffer[3]=X>>8;
      Buffer[4]=Y;
      Buffer[5]=Y>>8;
      Buffer[6]=R;
      send_package(Buffer);
#if us_delay
      delayMicroseconds(shape_delay*us_scale);
#else
      delay(shape_delay);
#endif
}


//-----------------------------------
// String Routine
// max 64 byte in string
// size s = 8x8 font
//      m = 16x16 GB2312-80 (External ROM)
//      b = 16x16 BIG5 (External ROM)
//-----------------------------------
//BROKEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

void print_string(unsigned int X, unsigned int Y, unsigned char *pstr, unsigned char size) {
      unsigned char TempData[3], Buffer[6], NoOfChar = 0, pos = 0;

      TempData[0]=2;            // use internal 8x8 font
      TempData[1]=0x10;
      if (size == 'm') TempData[2]=0x04;
      if (size == 'b') TempData[2]=0x05;
      else TempData[2] = 0x00;
      send_package(TempData);

      Buffer[0]=5;            // set the location
      Buffer[1]=0x12;
      Buffer[2]=X;
      Buffer[3]=X>>8;
      Buffer[4]=Y;
      Buffer[5]=Y>>8;
      send_package(Buffer);

      //NoOfChar = strlen((const char *)pstr); // send the string
      while ( pstr[NoOfChar] != '\0' && pos < 64)
      NoOfChar++;
      
      send_byte(0x17);
      send_byte(NoOfChar);
      while(*pstr>0) {
            send_byte(*pstr++);
      }
      close_byte();
}


void printchar(unsigned int X, unsigned int Y, unsigned char character) {
      unsigned char TempData[3], Buffer[6];

      TempData[0]=2;            // use internal 8x8 font
      TempData[1]=0x10;
      TempData[2]=0x00;
      send_package(TempData);

      Buffer[0]=5;            // set the location
      Buffer[1]=0x12;
      Buffer[2]=X;
      Buffer[3]=X>>8;
      Buffer[4]=Y;
      Buffer[5]=Y>>8;
      send_package(Buffer);

      send_byte(0x17);
      send_byte(1);
      send_byte(character);
      close_byte();
}

//-------------------------------------------
// Prints a 16-bit bitmap
//-------------------------------------------
void show_bmp( unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int * bmp) {
      unsigned char Buffer[5];
      unsigned int i,j,k;
      unsigned long p = 0;
      unsigned long addr = y*640 + 2*x;

      for (i = 0; i < h; i++) {
            Buffer[0] = 4;
            Buffer[1] = 0x81;
            Buffer[2] = addr;
            Buffer[3] = addr >> 8;
            Buffer[4] = addr >> 16;
            send_package(Buffer);
            j = w;
            while(j >= 16) {
                  send_byte(0x84);
                  send_byte(32);
                  for(k = 0; k < 16; k++) {
                        send_byte(bmp[p]);
                        send_byte(bmp[p]>>8);
                        p++;
                  }
                  close_byte();
                  j -= 16;
            }
            if (j > 0) {
                  send_byte(0x84);
                  send_byte(2*j);
                  for(k = 0; k < j; k++) {
                        send_byte(bmp[p]);
                        send_byte(bmp[p]>>8);
                        p++;
                  }
                  close_byte();
            }
            addr += 640;
      }
}


//---------------------------------------
// initialize a full screen direct draw 1 frame.
//---------------------------------------
void fdd_init(unsigned int line) {
      // the following 2 lines are the equivalent of addr = line * 640
      // however that overflows due to the size of the variable line?
      unsigned long addr = line*5;
      addr = addr << 7;
      
      unsigned char Buffer[5];
      Buffer[0] = 4;
      Buffer[1] = 0x81;
      Buffer[2] = addr;
      Buffer[3] = addr >> 8;
      Buffer[4] = addr >> 16;
      send_package(Buffer);
}

//--------------------------------------
// send a direct draw package consisting of 16 pixels
//--------------------------------------
void fdd_sendpackage( unsigned int *pkg ) {
      
      send_byte(0x84);
      send_byte(32);
      
      for (int i = 0; i < 16; i++) {
            send_byte(pkg[i]);
            send_byte(pkg[i]>>8);
      }
      close_byte();
      delayMicroseconds(110);
}


void init_lcd() {

      //-----------------------------------
      // init routine
      //-----------------------------------
      unsigned char F500[]={
            4,0x83,0x00,0xf5,0x00  };      // Reg[f500]=00 (internal MCS0 cycle pulse width)
      unsigned char F504[]={
            4,0x83,0x04,0xf5,0x04  };      // Reg[f504]=04 (internal MCS1 pulse width) 
      unsigned char F505[]={
            4,0x83,0x05,0xf5,0x80  };      // Reg[f505]=80 (internal MCS1 memory accessing setting)

      unsigned char F6C4[]={
            4,0x83,0xc4,0xf6,0x10  };      // Reg[f505]=80 Set Memory Clock Divide

      unsigned char F080[]={
            4,0x83,0x80,0xf0,0xfc  };      // Reg[f080]=fc (16bpp TFT)
      unsigned char F08E[]={
            4,0x83,0x8e,0xf0,0x32  };      // Reg[f08e]=32 (set pixel clock and LCD_ON)

      // set the LCD charactics
      unsigned char F090[]={
            4,0x83,0x90,0xf0,0x14  };
      unsigned char F091[]={
            4,0x83,0x91,0xf0,0x25  };      
      unsigned char F092[]={
            4,0x83,0x92,0xf0,0x1e  };      
      unsigned char F094[]={
            4,0x83,0x94,0xf0,0x05  };      
      unsigned char F095[]={
            4,0x83,0x95,0xf0,0x0e  };      
      unsigned char F096[]={
            4,0x83,0x96,0xf0,0x03  };

      

      // setup the port directions
      DDRD |= 0xFC; // set pins 2-7 on port D to be output
      DDRB |= 0x07; // set pins 0 and 1 on port B to be output
      //DDRD = 0xFF;
      DDRC = B00110111;


      //Initialize the ports
      //set command to 0xFF
      setLCDBUS(0xFF);
      CS_1;
      RES_0;
      A1_0;
      RD_1;
      WR0_1;

      RES_1;
      delay(1200);
      RES_0;
      delay(2);
      RES_1;
      delay(300);

      send_package(F500);
      send_package(F504);
      send_package(F505);

      send_package(F6C4);

      send_package(F080);
      send_package(F08E);

      send_package(F090);
      send_package(F091);
      send_package(F092);
      send_package(F094);
      send_package(F095);
      send_package(F096);
}