Character GPU Configuration

The Character GPU (CHRGPU) can be used to print both fonts and arbitrary symbols to the screen. For basic use you can print text to the screen and help debug your demo via outputting memory/registers to the screen. More advanced uses of the CHRGPU include building custom character maps that can be used to create 2D sprites for animation, games, and many other uses.

Full information on the CHRGPU can be found on page 51/76 of the PIC24F Section 43 Graphics Controller Module reference. To save some time, read below for a quick overview.

CHRGPU specs:


  • Maximum number of character maps: 256 (0xff)
  • Maximum character map entries: 65536 (0xffff)
  • Maximum character size: 256 x 256 pixels (0xff x 0xff)

CHRGPU Limitations:


  • All items in a given character map must be the same height (in pixels), but they *can* be different widths (in pixels).
  • Your color palette for both foreground and background color is limited by your bits per pixel (DPBPP/PUBPP) settings. If you are rendering a 1bpp buffer, you can only render 1bpp colored characters.
  • Your color scheme for characters is limited to 1bpp controlled by the foreground/background color registers. In order to draw characters with more than 2 colors (with the built in commands) you need to draw separate layers with transparency X times, where X is the number of distinct colors in your character.
  • If your VGA signal isn't perfectly aligned with the borders of your screen you can print characters that can't be seen. This is pretty common on resolutions lower than 640x480 when your starting print position is (0,0). For basic testing, you can use newlines and spaces to correct placement. Advanced usage would be to specify a new x,y starting point for all character rendering operations.
  • Character rotation is limited to pre-defined values that apply to an entire character map.
  • The CHRGPU only draws to Work Area 1!

Basic workflow for character rendering:

  • Initial Setup:
    • Set CHR_FONTBASE (Set base address of character map)
    • Set CHR_FGCOLOR (Set foreground color)
    • Set CHR_BGCOLOR (Set background color)
    • Set CHR_TEXTAREASTART (Set x,y start point of canvas)
    • Set CHR_TEXTAREAEND (Set x,y end point of canvas)
  • Printing:
    • Set CHR_PRINTPOS (Set x,y start point of character print)
    • Set CHR_PRINTCHAR (Print character)

***See the bottom of this post for example "Hello World!" code!***

Custom Configuration:

Character Rotation
Orientation is controlled by 2 bits (XXAAXXXX) in the first byte of each character map. This applies to the entire character map; you'll need to update and reload the character map each time you need a rotated character OR implement your own custom rotation code OR load multiple character maps each with a different rotation if you need rotation on a per-character basis.  Settings:

00 = Normal
01 = Characters rotated 270 degrees clockwise
10 = Characters rotated 180 degrees
11 = Characters rotated 90 degrees clockwise

Color Look Ups
If the Color Look Up Table (CLUT) is enabled, CHR_FGCOLOR and CHR_BGCOLOR will be interpretted as a CLUT color index instead of a literal color value.

Transparency
When you call CHR_PRINTCHAR, bit 8 of G1CMDH controls character transparency (Tr). If the Tr bit is set, CHR_BGCOLOR will not be drawn. This is required if you want to draw overlapping characters, or characters with more than two colors. In the latter case, you need to draw characters as a number of layers relative to how many colors your character requires. This is one of the primary limitations of the CHRGPU when your BPP > 1.

Custom Defined Symbols:

Generating your own symbols is as easy as modifying the Character Map Table (see below) to change the data lines to the bit arrangements for each character.

For example, this 0x41 =  "A" render as 6x8 1bpp:

0x1C,0x22,0x22,0x22,0x3E,0x22,0x22,0x00, // 0x41

This is how it looks in bits (note that it's truncated to 6 bits horizontally):

011100 // 0x1c
100010 // 0x22
100010 // 0x22
100010 // 0x22
111110 // 0x3e
100010 // 0x22
100010 //0x22
000000 // 0x00


Character Map Table Format:

// Someone should really make a nice struct version. BUT WHO?
uint8_t FontStart[] __attribute__((space(eds) section("FONTS"))) = {

// CHARACTER TABLE HEADER
    0x00, // XXAAXXXX - X = Reserved, AA = character orientation bits (Table 43-11)
    0x00, // Font ID (used by CHR_FONTBASE)
    0x00, 0x00, // First character ID # \__ The character map array indices. (Little endian!)
    0x7F, 0x00, // Last character ID #  /   They define the range of printable characters/symbols.
    0x08, // Height of characters, in pixels
    0x00, // Reserved - do not use

// CHARACTER OFFSET MAP
    // Format: A, B, C, D
    //     A - Width of THIS character
    //     B,C,D - 24 bit character table offset of character data (Little endian)
    6,8,4,0, //0x0 - offset is 0x000408
    6,16,4,0, //0x1 - offset is 0x000410
    6,24,4,0, //0x2 - offset is 0x000418
    // continue as needed

// CHARACTER DATA
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00
    0x1C,0x22,0x36,0x22,0x2A,0x22,0x1C,0x00, // 0x01
    0x1C,0x3E,0x2A,0x3E,0x22,0x3E,0x1C,0x00, // 0x02
    // continue as needed
};

Python Charmap Offset Generator

#!/usr/bin/python

height = 8 # height in pixels
width  = 8 # width in pixels

characters=128 # total characters in map
header_size = 8 # size of non-offset, non-data bytes at the start of each map
glyph_size = characters * 4 # total size of offset data

print "uint8_t FontStart[] __attribute__((space(eds) section(\"FONTS\"))) = {"
print "0x00, 0x00,", # need to add orientation here
print "0x00, 0x00,",
print "0x%02x, 0x00," % (characters-1),
print "0x%02x, 0x00," % (height)

for c in range(characters):
        off = "%06x" % (header_size + glyph_size + c*height)
        print "%d,%d,%d,%d, // %s" % (width,int(off[4:6],16),int(off[2:4],16),int(off[0:2],16),hex(c))

print "// Put Character Data here!";
print "};"

Basic configuration code:

main.c:

#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <xc.h>
#include <string.h>
#include "fonts.h"

#define  FCY    16000000UL    // Instruction cycle frequency, Hz
#include <libpic30.h>

#define HOR_RES 640UL
#define VER_RES 480UL
#define HOR_FRONT_PORCH 16
#define HOR_PULSE_WIDTH  96
#define HOR_BACK_PORCH 48
#define VER_FRONT_PORCH 10
#define VER_PULSE_WIDTH 2
#define VER_BACK_PORCH 33
#define BPP 1
#define CLOCKDIV 11

#define CHR_FGCOLOR        0x5000
#define CHR_BGCOLOR        0x5100
#define CHR_FONTBASE        0x5200
#define CHR_PRINTCHAR        0x5300
#define CHR_TXTAREASTART    0x5800
#define CHR_TXTAREAEND        0x5900
#define CHR_PRINTPOS        0x5A00
#define RCC_SRCADDR         0x6200
#define RCC_DESTADDR         0x6300
#define RCC_RECTSIZE         0x6400
#define RCC_COLOR         0x6600
#define RCC_STARTCOPY         0x6700

#define GFX_BUFFER_SIZE (HOR_RES * VER_RES / (8/BPP))

__eds__ uint8_t GFXDisplayBuffer[GFX_BUFFER_SIZE] __attribute__((eds));

void config_graphics(void) {
    _G1CLKSEL = 1;
    _GCLKDIV = CLOCKDIV;

    G1DPADRL = (unsigned long)(GFXDisplayBuffer) & 0xFFFF;
    G1DPADRH = 0;
    G1W1ADRL = (unsigned long)(GFXDisplayBuffer) & 0xFFFF;
    G1W1ADRH = 0;
    G1W2ADRL = (unsigned long)(GFXDisplayBuffer) & 0xFFFF;
    G1W2ADRH = 0;

    G1PUW = 640UL;
    G1PUH = 480UL;

    _GDBEN = 0xFFFF;

    // Using PIC24F manual section 43 page 37-38
    _DPMODE = 1;      /* TFT */
    _GDBEN = 0xFFFF;
    _DPW = _PUW = HOR_RES; // Work area and FB size so GPU works
    _DPH = _PUH = VER_RES;
    _DPWT = HOR_FRONT_PORCH + HOR_PULSE_WIDTH + HOR_BACK_PORCH + HOR_RES;// - 100;
    _DPHT = VER_FRONT_PORCH + VER_PULSE_WIDTH + VER_BACK_PORCH + VER_RES + 45;
    _DPCLKPOL = 0;
    _DPENOE = 0;
    _DPENPOL = 0;
    _DPVSOE = 1;      /* use VSYNC */
    _DPHSOE = 1;      /* use HSYNC */
    _DPVSPOL = 0;     /* VSYNC negative polarity */
    _DPHSPOL = 0;     /* HSYNC negative polarity */
    _ACTLINE = _VENST = VER_FRONT_PORCH + VER_PULSE_WIDTH + VER_BACK_PORCH - 16;
    _ACTPIX = _HENST = HOR_FRONT_PORCH + HOR_PULSE_WIDTH + HOR_BACK_PORCH;
    _VSST = VER_FRONT_PORCH;
    _HSST = HOR_FRONT_PORCH;
    _VSLEN = VER_PULSE_WIDTH;
    _HSLEN = HOR_PULSE_WIDTH;
    _DPPWROE = 0;
    _DPPINOE = 1;
    _DPPOWER = 1;
    _DPBPP = _PUBPP = 0;
    _G1EN = 1;
    __delay_ms(1);
}

void config_chr(void) {
    // Setup the base color values and starting position for font printing

    while(_CMDFUL) continue;
    G1CMDL = 0xFFFF;  // foreground color - 16 bit but you're restricted by BPP when on screen
    G1CMDH = CHR_FGCOLOR;
    Nop();

    while(_CMDFUL) continue;
    G1CMDL = 0x0000; // background color - 16 bit but you're restricted by BPP when on screen
    G1CMDH = CHR_BGCOLOR;
    Nop();

    while(_CMDFUL) continue;
    G1CMDL = (uint16_t)(FontStart) & 0xFFFF; // base address of character map from fonts.h. This must be aligned to a memory word boundary!
    G1CMDH = CHR_FONTBASE;
    Nop();

    while(_CMDFUL) continue;
    G1CMDL = 0; // Starting x,y of the canvas
    G1CMDH = CHR_TXTAREASTART;
    Nop();

    while(_CMDFUL) continue;
    G1CMDL = (HOR_RES & 0xF)<<12 | VER_RES; // Ending x,y of the canvas
    G1CMDH = CHR_TXTAREAEND | (HOR_RES >>4);
    Nop();
}

void  chr_fgcolor(uint16_t color) {
    // I haven't tested this function but it seems totally reasonable.
    while(_CMDFUL) continue;
    G1CMDL = color;
    G1CMDH = CHR_FGCOLOR;
    Nop();
}

void  chr_bgcolor(uint16_t color) {
    // I haven't tested this function but it seems totally reasonable.
    while(_CMDFUL) continue;
    G1CMDL = color;
    G1CMDH = CHR_BGCOLOR;
    Nop();
}

void chr_print(unsigned char *c) {
    /*
        Note: other examples use (char *c) but this will limit your character map range.
        Note: G1CMD format for CHR_PRINTPOS is (0x5A)(12 bit X value)(12 bit Y value)
        This gives you 4096x4096 addressable area, but the demo board is limited to
        roughly 640x480. In this case, you shouldn't have to set any high X bits in G1CMDH
        ***unless you are starting your print on the high end of the X axis.***. Adjust accordingly!
    */

    while(_CMDFUL) continue;
    G1CMDL = 0; // Set starting position x,y as (0,0) - Implement me separately for full control!
    G1CMDH = CHR_PRINTPOS;
    Nop();

    while(*c != NULL) {
        while(_CMDFUL) continue;
        G1CMDL = *c;
        G1CMDH = CHR_PRINTCHAR;
        Nop();
        c++;
    }
}

void rcc_draw(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
    // destination
    while(_CMDFUL) continue;
    G1CMDL = x + y * HOR_RES;
    G1CMDH = RCC_DESTADDR | (x + y * HOR_RES)>>16;
    Nop();

    // size
    while(_CMDFUL) continue;
    G1CMDL = (w<<12) | h;
    G1CMDH = RCC_RECTSIZE | (w>>4);
    Nop();

    // go!
    while(_CMDFUL) continue;
    G1CMDL = 0xC<<3 | 0<<7;
    G1CMDH = RCC_STARTCOPY;
    Nop();
}

void rcc_color(char color) {
    while(_CMDFUL) continue;
    G1CMDL = color;
    G1CMDH = RCC_COLOR;
    Nop();
}

void blank_background(void) {
    rcc_color(0x0000);
    rcc_draw(0,0,HOR_RES,VER_RES);
}

_CONFIG1(FWDTEN_OFF & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
_CONFIG2(POSCMOD_HS & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV2); //& FCKSM_CSDCMD
_CONFIG3(ALTPMP_ALTPMPEN & SOSCSEL_EC)

int main(void) {
    //OSCCON = 0x0000;
    _CPDIV = 0x0;
    ANSB = 0x0000;
    ANSC = 0x0000;
    ANSD = 0x0000;
    ANSF = 0x0000;
    ANSG = 0x0000;

    config_graphics();
    config_chr();

    while(1) {
        blank_background();
        chr_print((unsigned char *)"Hello!");
        __delay_ms(100);
    }   
}

fonts.h:

__eds__ uint8_t FontStart[] __attribute__((space(eds) section("FONTS"))) = {
// classic 8x6 bitmapped font
0x00, 0x00,
0x00, 0x00, // first char
0x7F, 0x00, // last char
0x08, 0x00, // height
// glyph table
6, // width 0
8,2,0,
6, // width 1
16,2,0,
6, // width 2
24,2,0,
6, // width 3
32,2,0,
6, // width 4
40,2,0,
6, // width 5
48,2,0,
6, // width 6
56,2,0,
6, // width 7
64,2,0,
6, // width 8
72,2,0,
6, // width 9
80,2,0,
6, // width 10
88,2,0,
6, // width 11
96,2,0,
6, // width 12
104,2,0,
6, // width 13
112,2,0,
6, // width 14
120,2,0,
6, // width 15
128,2,0,
6, // width 16
136,2,0,
6, // width 17
144,2,0,
6, // width 18
152,2,0,
6, // width 19
160,2,0,
6, // width 20
168,2,0,
6, // width 21
176,2,0,
6, // width 22
184,2,0,
6, // width 23
192,2,0,
6, // width 24
200,2,0,
6, // width 25
208,2,0,
6, // width 26
216,2,0,
6, // width 27
224,2,0,
6, // width 28
232,2,0,
6, // width 29
240,2,0,
6, // width 30,
248,2,0,
6, // width 31
0,3,0,
6, // width 32
8,3,0,
6, // width 33
16,3,0,
6, // width 34
24,3,0,
6, // width 35
32,3,0,
6, // width 36
40,3,0,
6, // width 37
48,3,0,
6, // width 38
56,3,0,
6, // width 39
64,3,0,
6, // width 40
72,3,0,
6, // width 41
80,3,0,
6, // width 42
88,3,0,
6, // width 43
96,3,0,
6, // width 44
104,3,0,
6, // width 45
112,3,0,
6, // width 46
120,3,0,
6, // width 47
128,3,0,
6, // width 48
136,3,0,
6, // width 49
144,3,0,
6, // width 50
152,3,0,
6, // width 51
160,3,0,
6, // width 52
168,3,0,
6, // width 53
176,3,0,
6, // width 54
184,3,0,
6, // width 55
192,3,0,
6, // width 56
200,3,0,
6, // width 57
208,3,0,
6, // width 58
216,3,0,
6, // width 59
224,3,0,
6, // width 60
232,3,0,
6, // width 61
240,3,0,
6, // width 62
248,3,0,
6, // width 63
0,4,0,
6, // width 64
8,4,0,
6, // width 65
16,4,0,
6, // width 66
24,4,0,
6, // width 67
32,4,0,
6, // width 68
40,4,0,
6, // width 69
48,4,0,
6, // width 70
56,4,0,
6, // width 71
64,4,0,
6, // width 72
72,4,0,
6, // width 73
80,4,0,
6, // width 74
88,4,0,
6, // width 75
96,4,0,
6, // width 76
104,4,0,
6, // width 77
112,4,0,
6, // width 78
120,4,0,
6, // width 79
128,4,0,
6, // width 80
136,4,0,
6, // width 81
144,4,0,
6, // width 82
152,4,0,
6, // width 83
160,4,0,
6, // width 84
168,4,0,
6, // width 85
176,4,0,
6, // width 86
184,4,0,
6, // width 87
192,4,0,
6, // width 88
200,4,0,
6, // width 89
208,4,0,
6, // width 90
216,4,0,
6, // width 91
224,4,0,
6, // width 92
232,4,0,
6, // width 93
240,4,0,
6, // width 94
248,4,0,
6, // width 95
0,5,0,
6, // width 96
8,5,0,
6, // width 97
16,5,0,
6, // width 98
24,5,0,
6, // width 99
32,5,0,
6, // width 100
40,5,0,
6, // width 101
48,5,0,
6, // width 102
56,5,0,
6, // width 103
64,5,0,
6, // width 104
72,5,0,
6, // width 105
80,5,0,
6, // width 106
88,5,0,
6, // width 107
96,5,0,
6, // width 108
104,5,0,
6, // width 109
112,5,0,
6, // width 110
120,5,0,
6, // width 111
128,5,0,
6, // width 112
136,5,0,
6, // width 113
144,5,0,
6, // width 114
152,5,0,
6, // width 115
160,5,0,
6, // width 116
168,5,0,
6, // width 117
176,5,0,
6, // width 118
184,5,0,
6, // width 119
192,5,0,
6, // width 120
200,5,0,
6, // width 121
208,5,0,
6, // width 122
216,5,0,
6, // width 123
224,5,0,
6, // width 124
232,5,0,
6, // width 125
240,5,0,
6, // width 126
248,5,0,
6, // width 127
0,6,0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00
0x1C,0x22,0x36,0x22,0x2A,0x22,0x1C,0x00, // 0x01
0x1C,0x3E,0x2A,0x3E,0x22,0x3E,0x1C,0x00, // 0x02
0x00,0x14,0x3E,0x3E,0x3E,0x1C,0x08,0x00, // 0x03
0x00,0x08,0x1C,0x3E,0x3E,0x1C,0x08,0x00, // 0x04
0x08,0x1C,0x1C,0x08,0x3E,0x3E,0x08,0x00, // 0x05
0x00,0x08,0x1C,0x3E,0x3E,0x08,0x1C,0x00, // 0x06
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x07
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x08
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x09
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x0A
0x00,0x38,0x30,0x2C,0x12,0x12,0x0C,0x00, // 0x0B
0x1C,0x22,0x22,0x1C,0x08,0x1C,0x08,0x00, // 0x0C
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x0D
0x30,0x2C,0x34,0x2C,0x34,0x36,0x06,0x00, // 0x0E
0x00,0x2A,0x1C,0x36,0x1C,0x2A,0x00,0x00, // 0x0F
0x04,0x0C,0x1C,0x3C,0x1C,0x0C,0x04,0x00, // 0x10
0x10,0x18,0x1C,0x1E,0x1C,0x18,0x10,0x00, // 0x11
0x08,0x1C,0x3E,0x08,0x3E,0x1C,0x08,0x00, // 0x12
0x14,0x14,0x14,0x14,0x14,0x00,0x14,0x00, // 0x13
0x3C,0x2A,0x2A,0x2C,0x28,0x28,0x28,0x00, // 0x14
0x1C,0x22,0x0C,0x14,0x18,0x22,0x1C,0x00, // 0x15
0x00,0x00,0x00,0x00,0x00,0x1E,0x1E,0x00, // 0x16
0x08,0x1C,0x3E,0x08,0x3E,0x1C,0x08,0x1C, // 0x17
0x08,0x1C,0x3E,0x08,0x08,0x08,0x08,0x00, // 0x18
0x08,0x08,0x08,0x08,0x3E,0x1C,0x08,0x00, // 0x19
0x00,0x08,0x18,0x3E,0x18,0x08,0x00,0x00, // 0x1A
0x00,0x08,0x0C,0x3E,0x0C,0x08,0x00,0x00, // 0x1B
0x00,0x00,0x00,0x02,0x02,0x02,0x3E,0x00, // 0x1C
0x00,0x14,0x14,0x3E,0x14,0x14,0x00,0x00, // 0x1D
0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x00,0x00, // 0x1E
0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00,0x00, // 0x1F
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x20
0x08,0x1C,0x1C,0x08,0x08,0x00,0x08,0x00, // 0x21
0x36,0x36,0x12,0x00,0x00,0x00,0x00,0x00, // 0x22
0x00,0x14,0x3E,0x14,0x14,0x3E,0x14,0x00, // 0x23
0x04,0x1C,0x02,0x0C,0x10,0x0E,0x08,0x00, // 0x24
0x26,0x26,0x10,0x08,0x04,0x32,0x32,0x00, // 0x25
0x04,0x0A,0x0A,0x04,0x2A,0x12,0x2C,0x00, // 0x26
0x0C,0x0C,0x04,0x00,0x00,0x00,0x00,0x00, // 0x27
0x08,0x04,0x04,0x04,0x04,0x04,0x08,0x00, // 0x28
0x04,0x08,0x08,0x08,0x08,0x08,0x04,0x00, // 0x29
0x00,0x14,0x1C,0x3E,0x1C,0x14,0x00,0x00, // 0x2A
0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00, // 0x2B
0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x04, // 0x2C
0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00, // 0x2D
0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00, // 0x2E
0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00, // 0x2F
0x1C,0x22,0x32,0x2A,0x26,0x22,0x1C,0x00, // 0x30
0x08,0x0C,0x08,0x08,0x08,0x08,0x1C,0x00, // 0x31
0x1C,0x22,0x20,0x18,0x04,0x02,0x3E,0x00, // 0x32
0x1C,0x22,0x20,0x1C,0x20,0x22,0x1C,0x00, // 0x33
0x10,0x18,0x14,0x12,0x3E,0x10,0x10,0x00, // 0x34
0x3E,0x02,0x02,0x1E,0x20,0x22,0x1C,0x00, // 0x35
0x18,0x04,0x02,0x1E,0x22,0x22,0x1C,0x00, // 0x36
0x3E,0x20,0x10,0x08,0x04,0x04,0x04,0x00, // 0x37
0x1C,0x22,0x22,0x1C,0x22,0x22,0x1C,0x00, // 0x38
0x1C,0x22,0x22,0x3C,0x20,0x10,0x0C,0x00, // 0x39
0x00,0x00,0x0C,0x0C,0x00,0x0C,0x0C,0x00, // 0x3A
0x00,0x00,0x0C,0x0C,0x00,0x0C,0x0C,0x04, // 0x3B
0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x00, // 0x3C
0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00, // 0x3D
0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00, // 0x3E
0x1C,0x22,0x20,0x18,0x08,0x00,0x08,0x00, // 0x3F
0x1C,0x22,0x3A,0x2A,0x3A,0x02,0x1C,0x00, // 0x40
0x1C,0x22,0x22,0x22,0x3E,0x22,0x22,0x00, // 0x41
0x1E,0x22,0x22,0x1E,0x22,0x22,0x1E,0x00, // 0x42
0x1C,0x22,0x02,0x02,0x02,0x22,0x1C,0x00, // 0x43
0x1E,0x22,0x22,0x22,0x22,0x22,0x1E,0x00, // 0x44
0x3E,0x02,0x02,0x1E,0x02,0x02,0x3E,0x00, // 0x45
0x3E,0x02,0x02,0x1E,0x02,0x02,0x02,0x00, // 0x46
0x1C,0x22,0x02,0x3A,0x22,0x22,0x3C,0x00, // 0x47
0x22,0x22,0x22,0x3E,0x22,0x22,0x22,0x00, // 0x48
0x1C,0x08,0x08,0x08,0x08,0x08,0x1C,0x00, // 0x49
0x20,0x20,0x20,0x20,0x22,0x22,0x1C,0x00, // 0x4A
0x22,0x12,0x0A,0x06,0x0A,0x12,0x22,0x00, // 0x4B
0x02,0x02,0x02,0x02,0x02,0x02,0x3E,0x00, // 0x4C
0x22,0x36,0x2A,0x22,0x22,0x22,0x22,0x00, // 0x4D
0x22,0x26,0x2A,0x32,0x22,0x22,0x22,0x00, // 0x4E
0x1C,0x22,0x22,0x22,0x22,0x22,0x1C,0x00, // 0x4F
0x1E,0x22,0x22,0x1E,0x02,0x02,0x02,0x00, // 0x50
0x1C,0x22,0x22,0x22,0x2A,0x12,0x2C,0x00, // 0x51
0x1E,0x22,0x22,0x1E,0x12,0x22,0x22,0x00, // 0x52
0x1C,0x22,0x02,0x1C,0x20,0x22,0x1C,0x00, // 0x53
0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 0x54
0x22,0x22,0x22,0x22,0x22,0x22,0x1C,0x00, // 0x55
0x22,0x22,0x22,0x22,0x22,0x14,0x08,0x00, // 0x56
0x22,0x22,0x2A,0x2A,0x2A,0x2A,0x14,0x00, // 0x57
0x22,0x22,0x14,0x08,0x14,0x22,0x22,0x00, // 0x58
0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x00, // 0x59
0x1E,0x10,0x08,0x04,0x02,0x02,0x1E,0x00, // 0x5A
0x1C,0x04,0x04,0x04,0x04,0x04,0x1C,0x00, // 0x5B
0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00, // 0x5C
0x1C,0x10,0x10,0x10,0x10,0x10,0x1C,0x00, // 0x5D
0x08,0x14,0x22,0x00,0x00,0x00,0x00,0x00, // 0x5E
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F, // 0x5F
0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00, // 0x60
0x00,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, // 0x61
0x02,0x02,0x1E,0x22,0x22,0x22,0x1E,0x00, // 0x62
0x00,0x00,0x1C,0x22,0x02,0x22,0x1C,0x00, // 0x63
0x20,0x20,0x3C,0x22,0x22,0x22,0x3C,0x00, // 0x64
0x00,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, // 0x65
0x18,0x04,0x04,0x1E,0x04,0x04,0x04,0x00, // 0x66
0x00,0x00,0x3C,0x22,0x22,0x3C,0x20,0x1C, // 0x67
0x02,0x02,0x0E,0x12,0x12,0x12,0x12,0x00, // 0x68
0x08,0x00,0x08,0x08,0x08,0x08,0x18,0x00, // 0x69
0x10,0x00,0x18,0x10,0x10,0x10,0x12,0x0C, // 0x6A
0x02,0x02,0x12,0x0A,0x06,0x0A,0x12,0x00, // 0x6B
0x08,0x08,0x08,0x08,0x08,0x08,0x18,0x00, // 0x6C
0x00,0x00,0x16,0x2A,0x2A,0x22,0x22,0x00, // 0x6D
0x00,0x00,0x0E,0x12,0x12,0x12,0x12,0x00, // 0x6E
0x00,0x00,0x1C,0x22,0x22,0x22,0x1C,0x00, // 0x6F
0x00,0x00,0x1E,0x22,0x22,0x22,0x1E,0x02, // 0x70
0x00,0x00,0x3C,0x22,0x22,0x22,0x3C,0x20, // 0x71
0x00,0x00,0x1A,0x24,0x04,0x04,0x0E,0x00, // 0x72
0x00,0x00,0x1C,0x02,0x1C,0x20,0x1C,0x00, // 0x73
0x00,0x04,0x1E,0x04,0x04,0x14,0x08,0x00, // 0x74
0x00,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, // 0x75
0x00,0x00,0x22,0x22,0x22,0x14,0x08,0x00, // 0x76
0x00,0x00,0x22,0x22,0x2A,0x3E,0x14,0x00, // 0x77
0x00,0x00,0x12,0x12,0x0C,0x12,0x12,0x00, // 0x78
0x00,0x00,0x12,0x12,0x12,0x1C,0x08,0x06, // 0x79
0x00,0x00,0x1E,0x10,0x0C,0x02,0x1E,0x00, // 0x7A
0x18,0x04,0x04,0x06,0x04,0x04,0x18,0x00, // 0x7B
0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x00, // 0x7C
0x0C,0x10,0x10,0x30,0x10,0x10,0x0C,0x00, // 0x7D
0x14,0x0A,0x00,0x00,0x00,0x00,0x00,0x00, // 0x7E
0x08,0x1C,0x36,0x22,0x22,0x3E,0x00,0x00, // 0x7F
};