public unsafe void Run()
        {
            var timer = new Timer();
            timer.start();

            // for fps info update
            int lastTick = timer.read_ms();

            string infoString = "";

            SDCardManager.Mount();

            _background = new Bitmap("BACK.DAT", 480, 272);
            _sprite = new Bitmap("SPRITE.DAT", 64, 64);
            _font = Font.LoadFromFile("DEJAVU.FNT");

            // create double buffered display
            var canvas = new Canvas();

            var sprites = new List<Sprite>();

            var r = new Random();

            for (int i = 0; i < 20; i++)
            {
                sprites.Add(new Sprite
                {
                    X = r.Next(480 - 64),
                    Y = r.Next(272 - 64),
                    Width = (int)_sprite.Width,
                    Height = (int)_sprite.Height,
                    Dx = r.Next(2) == 0 ? 2 : -2,
                    Dy = r.Next(2) == 0 ? 2 : -2
                });
            }

            while (true)
            {
                canvas.Clear(_background);

                foreach (var sprite in sprites)
                {
                    canvas.DrawBitmap(_sprite, 0, 0, sprite.X, sprite.Y, 64, 64);
                    sprite.Step(Canvas.ScreenWidth, Canvas.ScreenHeight);
                }

                // show info every couple of seconds
                if (timer.read_ms() - lastTick > 2000)
                {
                    // string.format broken?
                    //infoString = String.Format("FPS: {0} MEMAVAIL: {1} MEMALOC: {2}",
                    //    display.Fps,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory,
                    //    Microsoft.Zelig.Runtime.MemoryManager.Instance.AllocatedMemory);

                    infoString = "FPS: " + canvas.Fps.ToString() + " MEMAVAIL: " + Microsoft.Zelig.Runtime.MemoryManager.Instance.AvailableMemory.ToString();

                    lastTick = timer.read_ms();
                }

                canvas.DrawString(infoString, 0, 0, _font);

                // show the back buffer
                canvas.Flip();
            }
        }
        /// <summary>
        /// Draws a bitmap to the screen
        /// </summary>
        /// <param name="bitmap">bitmap to draw</param>
        /// <param name="sx">source x</param>
        /// <param name="sy">source y</param>
        /// <param name="dx">destination x</param>
        /// <param name="dy">destination y</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        public void DrawBitmap(Bitmap bitmap, int sx, int sy, int dx, int dy, int width, int height)
        {
            // clip rectangles
            Clip(ref dx, ref width, ref sx, _clip.X, _clip.Width);
            Clip(ref dy, ref height, ref sy, _clip.Y, _clip.Height);

            if (width > 0 && height > 0)
            {
                fixed (byte* ptr = bitmap.Data)
                {
                    DisplayInterop.LCD_DrawImageWithAlpha((UInt32*)ptr, sx, sy, bitmap.Width, dx, dy, width, height);
                }

                /*fixed (byte* ptr = bitmap.Data)
                {
                    UInt32* backBuffer = (UInt32*)GetBackBufferAddress();

                    UInt32* source = (UInt32*)ptr + (sx + sy * bitmap.Width);
                    UInt32* destination = backBuffer + (dx + dy * ScreenWidth);

                    int sourceRemain = bitmap.Width - width;
                    int destinationRemain = ScreenWidth - width;

                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            *destination = AlphaBlend(*destination, *source);
                            destination++;
                            source++;
                        }

                        source += sourceRemain;
                        destination += destinationRemain;
                    }
                }*/
            }
        }
        /// <summary>
        /// Load in font template file
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns>loaded font</returns>
        public static Font LoadFromFile(string fileName)
        {
            Font font = new Font();

            Dictionary<int, Page> pages = new Dictionary<int, Page>();
            Dictionary<char, Character> characters = new Dictionary<char, Character>();
            //Dictionary<Kerning, int> kernings = new Dictionary<Kerning, int>();

            byte[] data = SDCardManager.ReadAllBytes(fileName);

            int i = 0;
            int k;
            int l = 0;

            char[] lineChars = new char[255];

            string line;

            int commonWidth = 0, commonHeight = 0;

            while (i < data.Length)
            {
                k = i;

                l = 0;

                while (k < data.Length && data[k] != 10)
                {
                    if (data[k] != 10 && data[k] != 13)
                    {
                        lineChars[l] = (char)data[k];
                        l++;
                    }
                    k++;
                }

                line = new string(lineChars, 0, l);

                i = k + 1;

                string[] items = line.Split(' ');

                if (items.Length != 0)
                {
                    switch (items[0])
                    {
                        case "common":
                            commonWidth = GetInt(items, "scaleW");
                            commonHeight = GetInt(items, "scaleH");
                            break;
                        case "page":
                            int id = GetInt(items, "id");
                            string file = GetString(items, "file").Trim('"');
                            Bitmap texture = new Bitmap(file, commonWidth, commonHeight);
                            pages.Add(id, new Page(id, file, texture));
                            break;
                        case "char":
                            var character = new Character
                            {
                                Id = (char)GetInt(items, "id"),
                                Rect = new Rect(GetInt(items, "x"), GetInt(items, "y"), GetInt(items, "width"), GetInt(items, "height")),
                                Offset = new Point(GetInt(items, "xoffset"), GetInt(items, "yoffset")),
                                XAdvance = GetInt(items, "xadvance"),
                                Page = GetInt(items, "page"),
                                Channel = GetInt(items, "chnl")
                            };
                            characters.Add(character.Id, character);
                            break;
                        /*case "kerning":
                            var kerning = new Kerning
                            {
                                First = (char)GetInt(items, "first"),
                                Second = (char)GetInt(items, "second")
                            };
                            kernings.Add(kerning, GetInt(items, "amount"));
                            break;*/

                    }
                }
            }

            font.Pages = pages;
            font.Characters = characters;
            //font.Kernings = kernings;

            return font;
        }
        /// <summary>
        /// Clear the screen with given bitmap 
        /// </summary>
        /// <param name="bitmap">bitmap to clear with</param>
        public void Clear(Bitmap bitmap)
        {
            if (bitmap.Width != ScreenWidth || bitmap.Height != ScreenHeight)
            {
                throw new Exception("Bitmap has to match screen size");
            }

            int pixels = bitmap.Width * bitmap.Height;

            fixed (byte* ptr = bitmap.Data)
            {
                UInt32* back = (UInt32*)GetBackBufferAddress();
                UInt32* pixel = (UInt32*)ptr;

                UInt32 i;

                for (i = 0; i < pixels; i++)
                {
                    *back = *pixel;

                    // *back++ = *pixel++ bugged?
                    back++;
                    pixel++;
                }
            }
        }
 public Page(int id, string fileName, Bitmap texture)
 {
     FileName = fileName;
     Id = id;
     Texture = texture;
 }