Serial Wombat
a general-purpose digital interface device for hobbyists, engineers and students

 


Home
Overview
Protocol
Documentation
Getting Started
Connectivity
Pin Mode SDK Beta
Overview
Rules
Example 1
Example2
Example3
Graphic LCD
LED Display
Sample Projects
Downloads
Contact Us
Purchase
Forum

Did you know...

 

The ST2225A based Lite-On LED 14 segment AlphaNumeric Display

  I love the surplus electronics component market. You never know what you're gonna get. That's why I check All Electronic's New Items listing every few days. Very occasionally, a real gem of a part comes along. Now is one such occasion. This LED display is one of my favorite parts to come along in years. Here's why:

It's only $1! How can you go wrong? 7 alpha digits and 4 numerical digits, plus a driver IC for a buck? you gotta be kidding me. Granted, it's oddly shaped, and includes a bunch of oddball icons you probably don't want, and requires constant attention from the host, but when a 2 Alpha driverless part also goes for $1, it's hard to complain.

That said, it also has the standard curse of surplus hardware: No Datasheet. However, the datasheet for the driver ic, the ST2225A-M, is available. After a bit of hacking (I bought 5 displays just in case, but didn't ruin any this time...), I figured out the functions of the 5 pins on the back: +5v (lower left), ground (upper left), reset (upper right), spi clock (center top), and spi data (lower right). Lower center has no pin.

 

How the display works

(People just interested in using the Serial Wombat to drive the display can skip this section)

The Datasheet provided good information on how to control the driver IC. The ST2225A can drive up to 35 outputs. Obviously, the LED display has lots more than 35. So they had to be using multiplexing as displayed near the end of the datasheet. Figuring out what outputs lit what LED segments was the first trick. The datasheet describes the communication protocol:

  1. Set the reset line low
  2. Clock out 1 SPI Byte. The Most Significant bit of this Byte must be 1. The next 7 bits are outputs with the next MSB (0x40) being output driver 1.
  3. Clock out 3 more SPI bytes. These correspond to drivers 8 through 31.
  4. Clock out 1 more byte with drivers 32 through 35 in the most significant bits. I set the least significant 4 bits to 0.
  5. Set the reset line high

I used the Serial Wombat's SPI Master mode in order to send test packets. I created a C# app which would allow me to check boxes to set any of the 35 bits. Each time a box is clicked, a new packet is sent to the LED display.

Here's a zip of that app, which expects the chip select to be on Wombat Pin 20. Clock is on the SLK pin, and data on SDO pin.

It didn't take me long to find the common driver outputs. They're on driver outputs 30, 31, 32, 33 and 34. In any given packet only one these drivers should be enabled. The enabled common driver determines what LED segments are available to be driven by outputs 1 to 29. I marked up a photograph with which drivers drove what segments. The numbers are driver output numbers, the letters correspond to the commons ( A=30, B=31, C=32, D=33, E=34). Driver 35 appears unused. Some of the icons can apparently be turned on by more than one segment. (Click the image for full size)

In order to drive the display, you send a periodic stream of SPI packets alternating between A,B,C,D,and E, each with the proper segments set on the LCD. This should be done rapidly, ideally with no more than 5 ms between packets. The faster you send the packets, the less the display will appear to flash from segment to segment. The display will "hum" audibly while being used, so you may also consider what frequency is least annoying when you pick your update rate.

Obviously, this display isn't very smart. You can't tell it to display "A" on the leftmost segment. Instead, you must tell it to light segments A1, A2, A3, A5, A6, A13 and A9. You'll want a font which does this for you. The array in the Wombat SDK code below includes one. I did this font manually, as I couldn't think of a good way to do it automatically.

Originally, the display looked very dim. I was under the mistaken impression that the Reset line was actually the Chip Select line. Luckily, driving reset like a chip select mostly works. However, I discovered that it is only lit between the time that the segment 35 bit is received (see step 4 above) and when the reset went high (step 5 above). By varying that delay you can adjust the brightness of the display. This was really hit home when I tried to connect two devices to the spi, and found that they both showed a union of their respective data. I really wish they would have pinned out the Chip Select line, as the current implementation requries a separate clock pin for each display. This means that a micro's hardware spi unit can be used for only one display, and nothing else can use that clock line.

Be careful of letting the reset pin float, or be connected to a pin which powers up input. The first time I used a unit, the display came on, full blast, with all the displays lit at100%. The display was pulling about 450ma. My 7805 regulator got hot enough that my first indication there was a problem was the smell. It got pretty warm. Be warned...

A good solution to this problem is to use a pull-up resistor on the Reset line.

The display has a black mat mask sticker on top that can be removed. Just peel it off. Those boring Office Space icons go with it, leaving four glorious square LEDs. I fired up my Brother label printer and made some better icons. I intend to resell the display, along with a sheet of icons in the future from my web site. The mask does do a nice job of diffusing the Alpha / Seven Segment leds, making them a bit dimmer but much more readable. They're glairy (glareish? Is that a word?) without the mask. On one display I used an Exacto Knife to cut the mask so that I could peel off just the icons without removing the part covering the digits. This is what I suggest.

Here's the bitmap I intend to sell. Designed to be printed at 360 DPI (My Brother PT-3600 is higher resolution than typical 180 dpi printers) on 1 1/2 inch tape. Use clear background tape; white doesn't let enough light through. If you need a set of custom icons printed, contact me and I'll run you a set for $5. Use the graphic below for sizing.

Driving this display with the Serial Wombat

Obviously, since this display is rather dumb, it requires a smart controller. This is where the Serial Wombat comes in. This is an ideal application for a pin mode developed through the SDK, since it really isn't practical to continously send serial-port commands in order to properly display segments.

The pin mode created to drive this display (GET IT HERE!) can be used as is, or modified. It includes some rather gratuitous features such as a voltage and bargraph display, which could be removed if you wanted to save space for another pin mode. Further, the font tables cover 256 values, many more than will be required for most applications. In fact, many applications will work well with only digits and capital letters defined. This is only a concern for people who wish to modify the code or merge in other pin functions. These people may find that this pin mode uses up more user-area flash space than is necessary for their application.

People not using the Serial Wombat should be able to adapt the code pretty easily to their microcontroller. The code is designed to use the 18F4620's SPI hardware, or bit-bang communications if you're not using the SPI hardware pins.

The most common application of this pin mode will be to display host-provided text on the LED display. Doing this is very easy. Simply use the 200 command to configure whatever pin is connected to the Chip Select on the display. Provide and address in User RAM where the string to be displayed will be stored. Provide a delay value (if any) between the end of the serial sending sequence and Chip Select high in order to modify the brightness. Tell the display it's right-side up or upside down.

That's it. Whatever text is at the address you provide will be put on the display. Use the Set User RAM commands to put text in that memory. It's just that easy.

The pin mode is designed to be fun as well as useful (as-is) to most people using this display. There are a number of options:

  1. Upside down.
    One of the negatives of this display is that it is oddly shaped. Maybe you want the seven segment above the Alpha rather than below it. Or perhaps you only want to use the Alpha, but it will only fit where you want it if it's upside down. Or maybe you want to use two displays with the alphas one above another (The top one upside-down, the bottom one rightside up). All of these are good reasons that the pin-mode implements and upside-down option. Flip this bit and the fonts as well as the character order goes upside down. Strings are placed in user-ram the same way regardless of the upside down bit. Note that the upside down bit has no effect on the individually controlled icons, but the dots in the colons are reversed. That is, the top dot in the alpha colon becomes the bottom dot in the alpha colon, and the top dot in the seven segment colon becomes the bottom dot in the seven segment colon.  

    Two LED Displays, one upside down, one rightside up.

  2. Icon control. The dots in the colons, as well as the 4 icon LEDs can be individually controlled.
  3. Interrupt disable. You can tell the Wombat not to do anything else while the LEDs are momentarily lit for each segment. This prevents those annoying bright flashes that can occur (which result because the Wombat is late pulling up the reset line), especially when you're using timer interrupts or doing serial transactions. However, this can cause communications errors if the baud rate is too high or if the brightness delay is too long.
  4. The pin used for the clock line. As stated above, the lack of a chip-select means you need a separate clock line for each display. The SPI data line is always the same, pin 24. This flexibility allows multiple displays to be attached to a Serial Wombat.
  5. The delay between the end of transmission and asserting the reset line. The longer the wait, the brighter the display. But this is a timer based busy-wait, so it eats up CPU time, and is subject to variation if interrupts are not disabled.
  6. The address in user ram of the Alpha String
  7. The address in user ram of the numerical digits. By default this is 7 + the Alpha String address. But it can be changed to a different location so that multiple alpha strings from different displays can be placed side by side.

Modes:

  1. Text mode. In this mode the display shows a copy of text located in User Ram. Separate strings are used for the Alpha and 7 segment displays.
  2. Raw Mode. In this mode the display clocks out data stored in User Ram. The data is 25 bytes long. 5 bytes is clocked out each time the pin mode runs, then the sequence repeats. In this mode the individual led segments are set by the host. It is up to the host to set the proper "common" output (driver output 30 through 34).
  3. Display Public Data mode. In this mode the public data from another pin is displayed on the LEDs. The alpha shows the value in decimal, the 7-segment shows it in hex.
  4. Display Voltage. In this mode the public data from another pin is scaled to a value between 0 an 5. This can be used to show a voltage from one of the A/D pins (assuming the Serial Wombat power supply is 5 volts). The 7-segment shows that pin's public data in hex.
  5. Display Bargraph. In this mode the public data from another pin is displayed as a bargraph on the Alpha. The hex value of the pin is shown on the 7-segment.

 

Serial Wombat Commands

Some users will be able to get away with only using the first command. It configures the display to show host provided strings in the user ram area. It turns off interrupts, sets the display to right-side-up, turns off the icons and the colons, and allows the user to provide the ram address, the brightness delay, and the clock pin. It sets the 7 segment display address to the provided address + 7.

Data Sent to the Wombat: 200 Pin # 0xF0 User Ram address high byte User Ram address low byte Delay High Byte Delay Low Byte Clock Pin
Meaning: Configure pin first message Wombat Pin Number Connected to the LCD Reset pin First Add - on Command 16 bit index into user ram where the string to display can be found. Time to delay between the completion of a packet and setting the reset pin high. Each count is worth about 1/ 2millionth of a second. Wombat pin connected to the Serial Clock pin on the Display.
This message is echoed back by the Wombat.

The second command allows users to configure whether to disable interrupts while delaying, whether the display is upside down, the seven segment address, and what icons to display.

Data Sent to the Wombat: 201 Pin # 0xF0 Disable interrupts Icons/Bitmaps Upside Down Seven Segment User Ram Address High Byte Seven Segment User Ram Address Low Byte
Meaning: Configure pin second message Wombat Pin Number Connected to the LCD Reset pin First Add - on Command 0: Don't disable interrupts during delay

1: Disable interrupts during delay

Each of the 8 bits represents an icon or colon. Add numbers together to light multiple icons:
0x80: Alpha Bottom Colon
0x40: Alpha Top Colon
0x20: Right icon
0x10: Center right icon
0x08: Center left icon
0x04 Left icon
0x02 Bottom 7-seg colon
0x01 Top 7-seg colon
0: Seven Segments are on the bottom
1: Seven Segments are on the top
16 bit address representing the offset into the User Ram area where the Seven Segment display string starts. By default, this value is the Alphanumeric address + 7.
This message is echoed back by the Wombat.

The fourth command tells the wombat to clock out raw data stored in 25 bytes starting at the address provided in the 200 message. In each frame 5 bytes (40 bits) will be clocked out. This will cycle through 5 segments and back to the first.

Data Sent to the Wombat: 203 Pin # 0xF0 0x55 0x55 0x55 0x55 0x55
Meaning: Configure pin Fourth message Wombat Pin Number Connected to the LCD Reset pin First Add - on Command Unused.
This message is echoed back by the Wombat.

 

Here's the SDK. Use the xmodem option to download the .bin file to address 0xC000. The easiest way to do this is with the Wombat Panel under file...xmodem, although it can be done from a terminal following the instructions for the add on pack.

Questions or comments about this pin mode? Speak up in the forum!

Here's a quick look at the pin mode code for those who are just browsing:

 

 

 

 

 

#include "types.h"
#include "utilities.h"
#include "global_data.h"
#pragma code USERCODE
#pragma romdata USERDATA

// Define the possible states for this pin mode
#define PHONE_STATE_IDLE 0  // Does nothing
#define PHONE_STATE_FONT_A 1 // Calculate/send output bits for first common
#define PHONE_STATE_FONT_B 2 // Calculate/send output bits for 2nd common 
#define PHONE_STATE_FONT_C 3 // Calculate/send output bits for 3rd common
#define PHONE_STATE_FONT_D 4 // Calculate/send output bits for 4th common
#define PHONE_STATE_FONT_E 5 // Calculate/send output bits for 5th common
#define PHONE_STATE_RAW_A 6  // Send output bits supplied by host
#define PHONE_STATE_RAW_B 7  // Send output bits supplied by host
#define PHONE_STATE_RAW_C 8  // Send output bits supplied by host
#define PHONE_STATE_RAW_D 9  // Send output bits supplied by host
#define PHONE_STATE_RAW_E 10  // Send output bits supplied by host



extern rom const uint16 alpha_font[];
extern rom const uint8 sevenseg_font[];

void init_array(void);
void clock_out(void);
void rotate_alpha_font(void);
void rotate_sevenseg_font(void);

void init_user_code(void)
{

       if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_0)
       {
               // Get the 16 bit index into user ram where the display
               // bytes will be stored.  The first 7 bytes correspond to
               // the 14-segment alpha characters
               tp.generic.buffer = RXBUFFER16(3);
               tp.phoneled.seven_seg_address = tp.generic.buffer + 7;

               // Get how much extra delay should be added between the 
               // end of the transmission and setting the chip select high.
               // This will determine the apparent brightness of the display
               // since it is only "on" between reception of the 36th bit
               // and CS going high.
               tp.phoneled.delay = RXBUFFER16(5);
               tp.phoneled.spi_clk_pin = map_pin(rxbuffer[7]);


               // Set the state to start displaying fonts 
               tp.phoneled.state = PHONE_STATE_FONT_A;

               // By default don't disable interrupts between last send
               // and CS high
               tp.phoneled.disable_interrupts = 0;

               // By default, don't calculate output based on other pin's
               // public data.
               tp.phoneled.display_pin = 0xFF;
              tp.phoneled.display_mode = 0;
               tp.phoneled.icons.bitfield = 0; // All icons, colon off
               tp.phoneled.upside_down = 0;
       }
       if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_1)
       {
               // Allow the user to disable interrupts between data send
               // and CS high
               tp.phoneled.disable_interrupts = (rxbuffer[3] > 0) ;

               // bitfield determines which icons and colon segments are
               // turned on
               tp.phoneled.icons.bitfield = rxbuffer[4];

               tp.phoneled.upside_down = (rxbuffer[5] > 0);

           tp.phoneled.seven_seg_address = RXBUFFER16(6);
       }
       if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_2)
       {
               // Set up the display to display the public data
               // from some other pin or data source.  
               // rxbuffer[4] determines what to display.
               tp.phoneled.display_pin = map_pin(rxbuffer[3]);
               tp.phoneled.display_mode = rxbuffer[4];

       }
       if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_3)
       {
               // Set up the display to display raw strings from ram 
               tp.phoneled.state = PHONE_STATE_RAW_A;

       }

}


void update_raw_value(void);
void update_bar_graph(void);
void update_voltage(void);
void update_hex_value(void);

// update_user_code is called periodically.  
void update_user_code(void)
{
        switch (tp.phoneled.state)
        {
                case PHONE_STATE_IDLE:
                break;

                case PHONE_STATE_FONT_A:
                {
                    // First font state.  If necessary update the display
                    // string with the value from some other pin.  If
                    // display_mode == 0 then just display whatever
                    // string the host put in memory.

                    if (tp.phoneled.display_mode == 1)
                    {
                        //if display mode == 1 then display the raw
                        //value.  Decimal on the alpha, hex on the 7-seg
                            update_raw_value();
                            update_hex_value();
                    }
                    else if (tp.phoneled.display_mode == 2)
                    {
                            // Display a value between 0.0 and 5.0 on
                            // the alpha, the raw hex on the 7-seg
                            update_voltage();
                            update_hex_value();
                    }
                    else if (tp.phoneled.display_mode == 3)
                    {
                            // Display the value as a 21 segment bargraph
                            // which is full-scale at 65535.  Raw Hex
                            // value on 7-seg.
                            update_bar_graph();
                            update_hex_value();
                    }


                    // Now that we've updated the string (if necessary) display
                    // the segments which should be turned on for the first
                    // common.  The first common is bit 30.  

                    // Packet Bits: 
                    //1 through 14 : 1st alpha
                    //15: Top dot of bottom colon
                    //16: bottom dot of bottom colon
                    //18, 19: Mail Icon
                    //20, 21: Phone Icon
                    //22, 23: Disk Icon
                    //24, 25: Network icon
                    //26, 27: Top, bottom of top colon
                    //30: enable

                    // Set the start bit to 1, all the rest off.
                    init_array();

                    // Get the character to be displayed in the first alpha

                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 6];
                    }

                    // Get the 16 bit font representation for that character.
                    // The font is layed out so that the 14 segments are in
                    // the 14 middle bits of the 16.  That is, there's a 0
                    // in the MSB and a 0 in the LSB.
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }

                    // OR the character font bits into the first two bytes.
                    tp2.phoneled.array[0] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[1] |= tp2.phoneled.temp16.bytes.lowbyte;

                    // If the user wants the top dot of the 7-seg colon on,
                    // turn it on
                    if (tp.phoneled.icons.individual.bottomtopdot)
                    {
                            if (!tp.phoneled.upside_down)
                            {
                                    tp2.phoneled.array[1] |= 0x01;
                            }
                            else
                            {
                                    tp2.phoneled.array[2] |= 0x80;
                            }

                    }

                    // If the user wants the bottom dot of the 7-seg colon on,
                    // turn it on
                    if (tp.phoneled.icons.individual.bottombottomdot)
                    {
                            if (!tp.phoneled.upside_down)
                            {
                                    tp2.phoneled.array[2] |= 0x80;
                            }
                            else
                            {
                                    tp2.phoneled.array[1] |= 0x01;
                            }
                    }

                    // And so on...
                    if (tp.phoneled.icons.individual.mail)
                    {
                            tp2.phoneled.array[2] |= 0x30;
                    }
                    if (tp.phoneled.icons.individual.phone)
                    {
                            tp2.phoneled.array[2] |= 0x0C;
                    }
                    if (tp.phoneled.icons.individual.disk)
                    {
                            tp2.phoneled.array[2] |= 0x03;
                    }
                    if (tp.phoneled.icons.individual.network)
                    {
                            tp2.phoneled.array[3] |= 0xC0;
                    }
                    if (tp.phoneled.icons.individual.toptopdot)
                    {
                            if (!tp.phoneled.upside_down)
                            {
                                    tp2.phoneled.array[3] |= 0x20;
                            }
                            else
                            {
                                    tp2.phoneled.array[3] |= 0x10;

                            }
                    }
                    if (tp.phoneled.icons.individual.topbottomdot)
                    {
                            if (!tp.phoneled.upside_down)
                            {
                                    tp2.phoneled.array[3] |= 0x10;
                            }
                            else
                            {
                                    tp2.phoneled.array[3] |= 0x20;

                            }
                    }


                    // The Common for all of the "GROUP A" led segments is
                    // 30.  Set that bit to enable the common.
                     tp2.phoneled.array[3] |= 0x02 ; // Enable transistor 

                   // Send the data to the driver IC
                    clock_out();

                   // Next time, run the next common...
                    tp.phoneled.state = PHONE_STATE_FONT_B;
               }
                break;
                case PHONE_STATE_FONT_B:
                {
                    //1 through 14 : 2nd alpha
                    //15-21: Left 7-seg 
                    //22-28: Middle Right 7-seg
                    //31: enable

                    init_array();

                    // Get the character for the second Alpha.
                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 1];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 5];
                    }

                    //Get the font segments for that character.
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }

                    // Or them in...
                    tp2.phoneled.array[0] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[1] |= tp2.phoneled.temp16.bytes.lowbyte;

                    //Get the character for the first 7-seg
                    if (!tp.phoneled.upside_down)
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 0];
                    }
                    else
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 3];
                    }
                    // Get the 7-segment font for that character.
                    tp2.phoneled.temp8 = sevenseg_font[tp2.phoneled.temp8];

                    if (tp.phoneled.upside_down)
                    {
                            rotate_sevenseg_font();
                    }

                    // The 7 segment MSB is in Byte [1]'s LSB.  
                    if (tp2.phoneled.temp8 & 0x80)
                    {
                            tp2.phoneled.array[1] |= 0x01;
                    }

                    // The rest are in Byte [2], starting with the MSB.
                    tp2.phoneled.temp8 <<= 1;
                    tp2.phoneled.array[2] = tp2.phoneled.temp8;

                    // Get another fonted character
                    if (!tp.phoneled.upside_down)
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 2];
                    }
                    else
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 1];
                    }
                    tp2.phoneled.temp8 = sevenseg_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_sevenseg_font();
                    }

                    // And shift it around to fit in it's spot in the 
                    // 36 bit packet...
                    if (tp2.phoneled.temp8 & 0x80)
                    {
                            tp2.phoneled.array[2] |= 0x02;
                    }
                    if (tp2.phoneled.temp8 & 0x40)
                    {
                            tp2.phoneled.array[2] |= 0x01;
                    }
                    tp2.phoneled.temp8 <<= 2;
                    tp2.phoneled.array[3] = tp2.phoneled.temp8;

                    tp2.phoneled.array[3] |= 0x01;  //  Enable Transistor

                    // Send the packet
                    clock_out();
                    tp.phoneled.state = PHONE_STATE_FONT_C;
               }
               break;

                case PHONE_STATE_FONT_C:
                {
                    //1 through 14 : 3rd alpha
                    //15-21: Mid Left 7-seg 
                    //22-28: Right 7-seg
                    //32: enable
                    init_array();
                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 2];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 4];
                    }
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }
                    tp2.phoneled.array[0] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[1] |= tp2.phoneled.temp16.bytes.lowbyte;

                    if (!tp.phoneled.upside_down)
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 1];
                    }
                    else
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 2];
                    }
                    tp2.phoneled.temp8 = sevenseg_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_sevenseg_font();
                    }
                    if (tp2.phoneled.temp8 & 0x80)
                    {
                            tp2.phoneled.array[1] |= 0x01;
                    }
                    tp2.phoneled.temp8 <<= 1;
                    tp2.phoneled.array[2] = tp2.phoneled.temp8;

                    if (!tp.phoneled.upside_down)
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 3];
                    }
                    else
                    {
                        tp2.phoneled.temp8 = user_buffer[tp.phoneled.seven_seg_address + 0];
                    }

                    tp2.phoneled.temp8 = sevenseg_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_sevenseg_font();
                    }
                    if (tp2.phoneled.temp8 & 0x80)
                    {
                            tp2.phoneled.array[2] |= 0x02;
                    }
                    if (tp2.phoneled.temp8 & 0x40)
                    {
                            tp2.phoneled.array[2] |= 0x01;
                    }
                    tp2.phoneled.temp8 <<= 2;
                    tp2.phoneled.array[3] = tp2.phoneled.temp8;

                    tp2.phoneled.array[4] |= 0x80;  //  Enable Transistor

                    clock_out();
                    tp.phoneled.state = PHONE_STATE_FONT_D;
               }
               break;
                case PHONE_STATE_FONT_D:
                {
                    //1 through 14 : 4th alpha
                    //15-28: 6th Alpha 
                    //33: enable
                    init_array();
                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 3];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 3];
                    }
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }
                    tp2.phoneled.array[0] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[1] |= tp2.phoneled.temp16.bytes.lowbyte;

                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 5];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 1];
                    }
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }
                    if (tp2.phoneled.temp16.bytes.highbyte & 0x40)
                    {
                            tp2.phoneled.array[1] |= 0x01;
                    }
                    tp2.phoneled.temp16.u <<= 2;
                    tp2.phoneled.array[2] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[3] |= tp2.phoneled.temp16.bytes.lowbyte;

                    tp2.phoneled.array[4] |= 0x40;  //  Enable Transistor

                    clock_out();
                    tp.phoneled.state = PHONE_STATE_FONT_E;
               }
                break;
                case PHONE_STATE_FONT_E:
                {
                    //1 through 14 : 5th alpha
                    //15-28: 7th Alpha 
                    //34: enable
                    init_array();
                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 4];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 2];
                    }
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }
                    tp2.phoneled.array[0] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[1] |= tp2.phoneled.temp16.bytes.lowbyte;

                    if (!tp.phoneled.upside_down)
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 6];
                    }
                    else
                    {
                       tp2.phoneled.temp8 = user_buffer[tp.generic.buffer + 0];
                    }
                    tp2.phoneled.temp16.u = alpha_font[tp2.phoneled.temp8];
                    if (tp.phoneled.upside_down)
                    {
                            rotate_alpha_font();
                    }
                    if (tp2.phoneled.temp16.bytes.highbyte & 0x40)
                    {
                            tp2.phoneled.array[1] |= 0x01;
                    }
                    tp2.phoneled.temp16.u <<= 2;
                    tp2.phoneled.array[2] |= tp2.phoneled.temp16.bytes.highbyte;
                    tp2.phoneled.array[3] |= tp2.phoneled.temp16.bytes.lowbyte;

                    tp2.phoneled.array[4] |= 0x20;  //  Enable Transistor

                    clock_out();
                    tp.phoneled.state = PHONE_STATE_FONT_A;
               }
                break;

                case PHONE_STATE_RAW_A:
                case PHONE_STATE_RAW_B:
                case PHONE_STATE_RAW_C:
                case PHONE_STATE_RAW_D:
                case PHONE_STATE_RAW_E:
                {
		    tp2.phoneled.temp16.u8ptr = &user_buffer[tp.generic.buffer + 
                      (tp.phoneled.state - PHONE_STATE_RAW_A) * 5];

                    tp2.phoneled.array[0] = *tp2.phoneled.temp16.u8ptr;
                    ++tp2.phoneled.temp16.u8ptr;

                    tp2.phoneled.array[1] = *tp2.phoneled.temp16.u8ptr;
                    ++tp2.phoneled.temp16.u8ptr;

                    tp2.phoneled.array[2] = *tp2.phoneled.temp16.u8ptr;
                    ++tp2.phoneled.temp16.u8ptr;

                    tp2.phoneled.array[3] = *tp2.phoneled.temp16.u8ptr;
                    ++tp2.phoneled.temp16.u8ptr;

                    tp2.phoneled.array[4] = *tp2.phoneled.temp16.u8ptr;
                    ++tp2.phoneled.temp16.u8ptr;

                    clock_out();
                    if (tp.phoneled.state == PHONE_STATE_RAW_E)
                    {
                       tp.phoneled.state = PHONE_STATE_RAW_A;
                    }
                    else
                    {
                            ++tp.phoneled.state;
                    }

               }
               break;

        }

}


// The sw_spi_send allows us to use a user selected 
//clock pin.  This is necessary if multiple displays are to be used, 
//since the chip select isn't pinned out.  We still use the same data line 
//(the spi hardware SDO) for all displays, so we can cheat a bit and write 
//directly to the hardware, saving a few cycles per bit.  The 18F series is 
//pretty bad at rotates, so we unroll the loop to save time 
//(but at the expense of flash).

#define SW_CLOCK_BIT(_a) { \
if (tp2.phoneled.temp8 & _a){ LATCbits.LATC5 = \
1;} else\
 {LATCbits.LATC5 = 0; } \
pin_high(tp.phoneled.spi_clk_pin);pin_low(tp.phoneled.spi_clk_pin);}

static void sw_spi_send()
{
        SW_CLOCK_BIT(0x80);
        SW_CLOCK_BIT(0x40);
        SW_CLOCK_BIT(0x20);
        SW_CLOCK_BIT(0x10);
        SW_CLOCK_BIT(0x08);
        SW_CLOCK_BIT(0x04);
        SW_CLOCK_BIT(0x02);
        SW_CLOCK_BIT(0x01);
}

// This function sends the 5 bytes stored in tp2.phoneled.array to
// the LED driver chip using the 18F4620's hardware SPI peripheral.
void clock_out()
{
               if (tp.phoneled.spi_clk_pin == SCK_VIRTUAL_PIN)
               {
                // Set SPI clock and data to be outputs.
                pin_high(SDO_VIRTUAL_PIN);
                pin_low(SCK_VIRTUAL_PIN);

                         // Set polarity, data clocking according
                         // to LED driver data sheet and 18F4620
                         // documentation
                        SSPSTAT = 0;
                        SSPSTATbits.CKE = 1;
                        SSPCON1 = 0;
                        SSPCON1bits.CKP = 0;
                        SSPCON1 |= 2; //500 khz

                        // Enable SPI operation
                        SSPCON1bits.SSPEN = 1;

                        // Set the Chip Select Low
                       vpin_low();

                       //Clear the "finished" flag
                        PIR1bits.SSPIF = 0;

                        // Send the first byte
                       SSPBUF = tp2.phoneled.array[0];

                       //Wait until finished
                        while(PIR1bits.SSPIF == 0);

                        // Done.  Send the second byte
                        PIR1bits.SSPIF = 0;
                       SSPBUF = tp2.phoneled.array[1];
                        while(PIR1bits.SSPIF == 0);

                        // Send the third byte
                        PIR1bits.SSPIF = 0;
                       SSPBUF = tp2.phoneled.array[2];
                        while(PIR1bits.SSPIF == 0);

                        // Send the fourth byte
                        PIR1bits.SSPIF = 0;
                       SSPBUF = tp2.phoneled.array[3];
                        while(PIR1bits.SSPIF == 0);
                        PIR1bits.SSPIF = 0;

                        // The LEDs will light after bit 36 is received,
                        // and stay on until the chip select goes high.
                        // If an interrupt comes between these points,
                        // then the time "on" may be extended.  To
                        // ensure constant apparent brightness, interrupts
                        // can be disabled for this period.  However,
                        // this may cause problems with other 
                        // functions which use those interrupts if the
                        // disabled period is too long. 
                        if (tp.phoneled.disable_interrupts)
                       {
                               DISABLE_ALL_INTERRUPTS();
                       }

                        // Send the 5th byte
                       SSPBUF = tp2.phoneled.array[4];
                        while(PIR1bits.SSPIF == 0);
                        PIR1bits.SSPIF = 0;

                        // If desired, wait for some time while the 
                        // leds are "on" to effectively increase the duty
                        // cycle.
                        if (tp.phoneled.delay >0)
                        {
                                delay_cycles16(tp.phoneled.delay);
                        }

                        // Set chip select high
                        vpin_high();

                        // Reenable interrupts if we disabled them.
                       if (tp.phoneled.disable_interrupts)
                       {
                               ENABLE_ALL_INTERRUPTS();
                       }

                       // Shut off the SPI hardware.
                        SSPCON1bits.SSPEN = 0;
               }
               else
               {
                       //Not using the spi hardware.  Do in software
                // Set SPI clock and data to be outputs.
                pin_high(SDO_VIRTUAL_PIN);
                pin_low(tp.phoneled.spi_clk_pin);


                        // Set the Chip Select Low
                       vpin_low();


                        // Send the first byte
                       tp2.phoneled.temp8 = tp2.phoneled.array[0];

                       sw_spi_send();

                        // Done.  Send the second byte
                       tp2.phoneled.temp8 = tp2.phoneled.array[1];
                       sw_spi_send();

                        // Send the third byte
                       tp2.phoneled.temp8 = tp2.phoneled.array[2];
                       sw_spi_send();

                        // Send the fourth byte
                       tp2.phoneled.temp8 = tp2.phoneled.array[3];
                       sw_spi_send();

                        // The LEDs will light after bit 36 is received,
                        // and stay on until the chip select goes high.
                        // If an interrupt comes between these points,
                        // then the time "on" may be extended.  To
                        // ensure constant apparent brightness, interrupts
                        // can be disabled for this period.  However,
                        // this may cause problems with other 
                        // functions which use those interrupts if the
                        // disabled period is too long. 
                        if (tp.phoneled.disable_interrupts)
                       {
                               DISABLE_ALL_INTERRUPTS();
                       }

                        // Send the 5th byte
                       tp2.phoneled.temp8 = tp2.phoneled.array[4];
                       sw_spi_send();

                        // If desired, wait for some time while the 
                        // leds are "on" to effectively increase the duty
                        // cycle.
                        if (tp.phoneled.delay >0)
                        {
                                delay_cycles16(tp.phoneled.delay);
                        }

                        // Set chip select high
                        vpin_high();

                        // Reenable interrupts if we disabled them.
                       if (tp.phoneled.disable_interrupts)
                       {
                               ENABLE_ALL_INTERRUPTS();
                       }

                       // Shut off the SPI hardware.
               }
}

void init_array()
{
        tp2.phoneled.array[0] = 0x80; // First bit is a start bit
        tp2.phoneled.array[1] = 0x00;
        tp2.phoneled.array[2] = 0x00;
        tp2.phoneled.array[3] = 0x00;
        tp2.phoneled.array[4] = 0x00;
}


// The function update_raw_value gets the public data from the pin in
// tp.phoneled.display_pin and puts it into the first seven locations
// in user ram starting at location tp.generic.buffer.  Since a 
// 16-bit value can take up at most 5 digits in decimal, the first
// two of the 7 alpha characters are set to 'space'.  The routine
// assumes that the first 10 entries in the Alpha font array
// are the characters '0' to '9'.  Converting it to use the 
// ASCII characters would be easy if desired.
//
// This routine uses repeated subtraction rather than division to
// break the binary value down into an array of decimal digits.
// This works well because the number of operations is bounded to a maximum of
// 9 for any digit (6 for the leading digit).  Use of the actual division
// algorithm would require pulling in a library function as well as doing
// a mutiply and subtraction to get the remainder after each digit.
// As an additional optimization the calculation of the 10's digit can
// be done in 8-bit rather than 16 bit math, and the 1's digit requires
// no calculation.

void update_raw_value()
{
        // Get the data and put it in a 16 bit buffer.  The mixed16_t is
        // used to allow easy access to the data either as a 16 bit or two
        // 8 bit values
        tp2.phoneled.temp16.u = get_buffer(tp.phoneled.display_pin);

        // temp8 will be used for a counter to count the number of
        // decrements
        tp2.phoneled.temp8 = 0;

        // Blank the first two characters
        user_buffer[tp.generic.buffer] = ' ';
        user_buffer[tp.generic.buffer+1] = ' ';

        // Get the number of tenthousands
        while (tp2.phoneled.temp16.u >= 10000)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 10000;
        }
        // And put it in the string
        user_buffer[tp.generic.buffer + 2] = tp2.phoneled.temp8;


        // Get the number of thousands
        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.u >= 1000)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 1000;
        }
        user_buffer[tp.generic.buffer + 3] = tp2.phoneled.temp8;

        //Get the number of hundreds
        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.u >= 100)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 100;
        }
        user_buffer[tp.generic.buffer + 4] = tp2.phoneled.temp8;

        // Get the number of 10s.  Switch to 8 bit math, since
        // all values are guaranteed to be less than 256.
        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.bytes.lowbyte >= 10)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.bytes.lowbyte -= 10;
        }
        user_buffer[tp.generic.buffer + 5] = tp2.phoneled.temp8;
        user_buffer[tp.generic.buffer + 6] = tp2.phoneled.temp16.bytes.lowbyte;
        // Now, clear out the leading zeros with spaces.  Move left to write
        // blanking zeros until we either blank 4 zeros or get to a non-zero
        // number
        for (tp2.phoneled.temp8 = 2; tp2.phoneled.temp8 <= 5; ++tp2.phoneled.temp8)
        {
                if (user_buffer[tp.generic.buffer + tp2.phoneled.temp8] == 0)
                {
                   user_buffer[tp.generic.buffer + tp2.phoneled.temp8] =' ';
                }
                else
                {
                        // Non zero.  Stop.
                        break;
                }
        }

}

#define VERTICAL_LINE_LEFT 16 //From the font table below
#define TWO_VERTICAL_LINES_LEFT 18 
#define THREE_VERTICAL_LINES 20
void update_bar_graph()
{
        // There are 21 available segments, 3 each in 7 items. 
        // Use a series of writes to the buffer to display the graph.
        // There's probably a fancier algorithm than this, but this
        // one is straight forward.  Go through each character, left
        // to right, determining how many bars in that character should
        // be written.  The values were determined with an Excel spreadsheet. 
        // Magic numbers like this used to make my CS professior mad.  But
        // he isn't here, is he?  :-)

        tp2.phoneled.temp16.u = get_buffer(tp.phoneled.display_pin);
        for (tp2.phoneled.temp8 = 0; tp2.phoneled.temp8 < 7; ++ tp2.phoneled.temp8)
        {
                user_buffer[tp.generic.buffer + tp2.phoneled.temp8] = ' ';
        }

        // Check for Three lines first.  If not, check for two.  If not,
        // check for one.  Otherwise leave it set for none.
        if (tp2.phoneled.temp16.u >= 9362)
        {
                user_buffer[tp.generic.buffer] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 6241)
        {
                user_buffer[tp.generic.buffer] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 3120)
        {
                user_buffer[tp.generic.buffer] = VERTICAL_LINE_LEFT;
        }

        // Do the same for the second segment, and so on...
        if (tp2.phoneled.temp16.u >= 18724)
        {
                user_buffer[tp.generic.buffer + 1] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 15603)
        {
                user_buffer[tp.generic.buffer + 1] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 12482)
        {
                user_buffer[tp.generic.buffer + 1] = VERTICAL_LINE_LEFT;
        }

        if (tp2.phoneled.temp16.u >= 28086)
        {
                user_buffer[tp.generic.buffer + 2] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 24965)
        {
                user_buffer[tp.generic.buffer + 2] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 21845)
        {
                user_buffer[tp.generic.buffer + 2] = VERTICAL_LINE_LEFT;
        }

        if (tp2.phoneled.temp16.u >= 37448)
        {
                user_buffer[tp.generic.buffer + 3] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 34327)
        {
                user_buffer[tp.generic.buffer + 3] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 31207)
        {
                user_buffer[tp.generic.buffer + 3] = VERTICAL_LINE_LEFT;
        }

        if (tp2.phoneled.temp16.u >= 46810)
        {
                user_buffer[tp.generic.buffer + 4] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 43690)
        {
                user_buffer[tp.generic.buffer + 4] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 40569)
        {
                user_buffer[tp.generic.buffer + 4] = VERTICAL_LINE_LEFT;
        }

        if (tp2.phoneled.temp16.u >= 56172)
        {
                user_buffer[tp.generic.buffer + 5] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 53052)
        {
                user_buffer[tp.generic.buffer + 5] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 49931)
        {
                user_buffer[tp.generic.buffer + 5] = VERTICAL_LINE_LEFT;
        }

        if (tp2.phoneled.temp16.u >= 65535)
        {
                user_buffer[tp.generic.buffer + 6] = THREE_VERTICAL_LINES;
        }
        else if (tp2.phoneled.temp16.u >= 62414)
        {
                user_buffer[tp.generic.buffer + 6] = TWO_VERTICAL_LINES_LEFT;
        }
        else if (tp2.phoneled.temp16.u >= 59293)
        {
                user_buffer[tp.generic.buffer + 6] = VERTICAL_LINE_LEFT;
        }
}


// The update_voltage function scales a number between 0 and 65535 to
// a number between 0 and 5.0 .  A lot of newbies think that you
// need floats to do this, but you really don't.  You can do it with
// fixed point math (fractions with denominators which are powers of 2)
// This could easily be scaled to other ranges besides 0 to 5.0 by changing
// the constants
void update_voltage()
{
        mixed32_t voltage;  // 32 bit value 
        // voltage = input * 5 / 65535.  Approximate as 5  / 65536.
        // Multiply input value by 5 to get a value in 65536ths, and 
        // Multiply by 10000 to increase that to 10000ths of a volt in 
        // 65536ths 

        tp2.phoneled.temp16.u = get_buffer(tp.phoneled.display_pin);
        voltage.u = ((unsigned long) 5 * 10000 )  * tp2.phoneled.temp16.u ;

        // Now, take the top 16 bits to get the results in tenthousandths

        tp2.phoneled.temp16.u = voltage.uwords.h;
        tp2.phoneled.temp8 = 0;
        user_buffer[tp.generic.buffer] = ' ';
        user_buffer[tp.generic.buffer + 6] = ' ';
        while (tp2.phoneled.temp16.u >= 10000)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 10000;
        }
        user_buffer[tp.generic.buffer + 1] = tp2.phoneled.temp8;

        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.u >= 1000)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 1000;
        }
        user_buffer[tp.generic.buffer + 2] = tp2.phoneled.temp8;

        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.u >= 100)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.u -= 100;
        }
        user_buffer[tp.generic.buffer + 3] = tp2.phoneled.temp8;

        tp2.phoneled.temp8 = 0;
        while (tp2.phoneled.temp16.bytes.lowbyte >= 10)
        {
                ++tp2.phoneled.temp8;
                tp2.phoneled.temp16.bytes.lowbyte -= 10;
        }
        user_buffer[tp.generic.buffer + 4] = tp2.phoneled.temp8;
        user_buffer[tp.generic.buffer + 5] = tp2.phoneled.temp16.bytes.lowbyte;

}


// update_hex_values sets the characters associated with the 7 segment
// display to the hex value of the desired pin.  Pretty easy, since all
// you have to do is either mask or shift bytes.  A mixed16_t union is
// used to allow easy access to either the entire 16 bits or inividual
// bytes.
void update_hex_value()
{
        tp2.phoneled.temp16.u = get_buffer(tp.phoneled.display_pin);
        user_buffer[tp.phoneled.seven_seg_address ] = (tp2.phoneled.temp16.bytes.highbyte >> 4);
        user_buffer[tp.phoneled.seven_seg_address + 1] = (tp2.phoneled.temp16.bytes.highbyte & 0x0F);
        user_buffer[tp.phoneled.seven_seg_address + 2] = (tp2.phoneled.temp16.bytes.lowbyte >> 4);
        user_buffer[tp.phoneled.seven_seg_address + 3] = (tp2.phoneled.temp16.bytes.lowbyte & 0x0F);



}



// The following array is used to create the font for the 14 segment
// characters.  The use of ORed #defines makes it easy to change the characters
// all at the same time (such as turning them upside down, backwards, or
// rearanging the bit assignments for different displays).  
// The way they're set up now is designed to make them most ready to
// directly OR into the All electronics display.
//
// I made these by hand, so they may not match whatever is most
// standard.  Also, some of the lower case letters look bad, or
// are just the same as upper case (try to make a lower case g...)
// and others, such as "&" are subtituted (i used "+").  A lot of
// other non-ascii values have patterns I thought were fun or 
// useful.  feel free to modify them.  Note that the functions
// above assume 0 through 15 in the array to be 0..9,A..F
// These tables could be cut off above 'Z' or 127 if you were willing
// to make sure that the host only tried to display characters in that
// range.

//             0x4000_
//          
//0x0200 | 0x0002\   0x0100|   0x0080/    | 0x2000
//
//             -0x0004       -0x0040
//
//       0x0008/      0x0010|   0x0020\
//
//0x0400 |              | 0x1000
//            _ 0x0800
#define TOP 0x4000
#define RIGHTTOP 0x2000
#define RIGHTBOTTOM 0x1000
#define BOTTOM 0x0800
#define LEFTBOTTOM 0x0400
#define LEFTTOP 0x0200
#define NORTH 0x0100
#define NE 0x0080
#define EAST 0x0040
#define SE 0x0020
#define SOUTH 0x0010
#define SW 0x0008
#define WEST 0x0004
#define NW 0x0002
#define ALL_OFF 0

rom const uint16 alpha_font[] =  {
   TOP | LEFTTOP | LEFTBOTTOM|BOTTOM|RIGHTBOTTOM|RIGHTTOP|SW|NE, // 0
   RIGHTBOTTOM|RIGHTTOP, // 1
   TOP|RIGHTTOP | EAST|WEST|LEFTBOTTOM|BOTTOM , // 2
   TOP|RIGHTTOP | RIGHTBOTTOM|EAST| BOTTOM , // 3
   RIGHTTOP | LEFTTOP|EAST|WEST| RIGHTBOTTOM , // 4
    LEFTTOP | TOP| WEST|SE|BOTTOM , // 5
    LEFTTOP | TOP| WEST|EAST |LEFTBOTTOM|RIGHTBOTTOM|BOTTOM , // 6
    TOP| RIGHTBOTTOM|RIGHTTOP, // 7
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTTOP|EAST|WEST|BOTTOM, // 9
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST, // 10 'A'
    TOP| RIGHTBOTTOM|RIGHTTOP| NORTH |SOUTH|EAST|BOTTOM, // 11 'B'
    TOP|  LEFTBOTTOM|LEFTTOP| BOTTOM, //12 'C' 
    TOP| RIGHTBOTTOM|RIGHTTOP| NORTH |SOUTH|BOTTOM, // 13 'D'
    TOP|  LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM, // 14 'E'
    TOP|  LEFTBOTTOM|LEFTTOP|WEST, // 15 'F'
    LEFTBOTTOM|LEFTTOP, // 16 VERTICAL LINE LEFT
    RIGHTBOTTOM|RIGHTTOP,// 17 VERTICAL LINE RIGHT 
    LEFTBOTTOM|LEFTTOP|NORTH|SOUTH, // 18  TWO VERTICAL LINES LEFT
     RIGHTTOP | RIGHTBOTTOM | NORTH | SOUTH, // 19  TWO VERTICAL LINES RIGHT
    RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|NORTH|SOUTH, // 20  THREE VERTICAL LINES 
    TOP, // 21 TOP HORIZONTAL LINE 
    TOP|EAST|WEST|BOTTOM , // 22 THREE HORIZONTAL LINES 
    SOUTH|SE|SW, // 23 NORTH ARROW 
    SW|WEST|SOUTH, // 24 NE Arrow 
    WEST|NW|SW, //25 East Arrow 
     NW|NORTH|WEST, //26 SE Arrow
     NORTH|NE|NW, //27 SOUTH ARROW
     NE|NORTH|EAST, //  28 SW ARROW
     EAST|NE|SE, //29 WEST ARRAOW
     SE|SOUTH|EAST, // 30 NW ARROW
     TOP|BOTTOM|RIGHTTOP|RIGHTBOTTOM|LEFTTOP|LEFTBOTTOM|NORTH|WEST|SOUTH|EAST, //31 ,  BOXED CROSS
    ALL_OFF, // 32 SPACE
    NORTH|BOTTOM, // 33 '!' 
    LEFTTOP|NORTH, // 34 '"' 
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|NORTH|SOUTH, // 35 '#' 
    TOP|RIGHTTOP| LEFTBOTTOM|EAST|WEST|BOTTOM | NW|SE, // 36 '$'
    LEFTTOP|RIGHTBOTTOM | SW|NE, // 37 '%' 
    EAST|WEST|NORTH|SOUTH, // 38 '&' impelemnted as + 
    NORTH, // 39 ''' 
    NE|SE, // 40 '(' 
    NW|SW, // 41 ')' 
    NORTH|SOUTH| EAST|WEST|NW|SW|NE|SE, // 42 '*' 
    NORTH|SOUTH| EAST|WEST, // 43 '+' 
    SW, // 44 ','
    EAST|WEST, // 45 '-'
    LEFTBOTTOM|WEST|BOTTOM |SOUTH, // 46 '.'
    SW|NE, // 47 '/'
   TOP | LEFTTOP | LEFTBOTTOM|BOTTOM|RIGHTBOTTOM|RIGHTTOP|SW|NE, // 48 '0'
   RIGHTBOTTOM|RIGHTTOP, // '1'
   TOP|RIGHTTOP | EAST|WEST|LEFTBOTTOM|BOTTOM , // '2'
   TOP|RIGHTTOP | RIGHTBOTTOM|EAST| BOTTOM , // '3'
   RIGHTTOP | LEFTTOP|EAST|WEST| RIGHTBOTTOM , // '4'
    LEFTTOP | TOP| WEST|SE|BOTTOM , // '5'
    LEFTTOP | TOP| WEST|EAST |LEFTBOTTOM|RIGHTBOTTOM|BOTTOM , // '6'
    TOP| RIGHTBOTTOM|RIGHTTOP, // '7'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM, // '8'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTTOP|EAST|WEST|BOTTOM, // '9'
    TOP|BOTTOM,  // 58 ':'
    TOP| SW, // 59 ';'
    NE|SE, // 60 '<'
    EAST|WEST|BOTTOM , // 61 '='
    NW|SW, // 62 '>'
    TOP| RIGHTTOP| EAST|SOUTH, // 63 '?'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|BOTTOM | SOUTH, // 64 '@'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST, // 65 'A'
    TOP| RIGHTBOTTOM|RIGHTTOP| NORTH |SOUTH|EAST|BOTTOM, // 66 'B'
    TOP|  LEFTBOTTOM|LEFTTOP|BOTTOM, //67 'C' 
    TOP| RIGHTBOTTOM|RIGHTTOP| NORTH |SOUTH|BOTTOM, // 68 'D'
    TOP|  LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM, // 69 'E'
    TOP|  LEFTBOTTOM|LEFTTOP|WEST, // 70 'F'
    TOP| RIGHTBOTTOM| LEFTBOTTOM|LEFTTOP|EAST|BOTTOM , // 'G'
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST, // 'H'
     NORTH|SOUTH, // 'I'
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|BOTTOM, // 'J'
      LEFTBOTTOM|LEFTTOP|WEST| NE|SE, // 'K'
     LEFTBOTTOM|LEFTTOP|BOTTOM , // 'L'
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP| NW|NE, // 'M'
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP| NW|SE, // 'N'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|BOTTOM , // 'O'
    TOP| RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST, // 80 'P'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|BOTTOM |SE, // 'Q'
    TOP| RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|SE, // 'R' 
    TOP| RIGHTBOTTOM| LEFTTOP|EAST|WEST|BOTTOM , // 'S'
    TOP | NORTH|SOUTH, //'T' 
     RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|BOTTOM , // 'U'
     LEFTBOTTOM|LEFTTOP|SW|NE, //'V' 
    RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|SW|SE, // 'W'
     NW|SW|NE|SE, // 'X'
     NW|NE|SOUTH,//'Y'
    TOP| BOTTOM | SW|NE, // 'Z'
    NE|SE, // 91 '[' implemented as (
     NW|SE, // 92 '\' 
    NW|SW, // 93 ']' implemented as ) 
    RIGHTTOP|NE, // 94 '^'
    BOTTOM, // 95 '_'
    NW, // '`' 
    LEFTBOTTOM|WEST|BOTTOM |SOUTH, // 'a'
     LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | RIGHTBOTTOM, //  'b'
     LEFTBOTTOM|EAST|WEST|BOTTOM , // 'c'
     LEFTBOTTOM|RIGHTTOP|EAST|WEST|BOTTOM | RIGHTBOTTOM, //  'd'
     LEFTBOTTOM|WEST|BOTTOM |SW, // 'e' 
    SOUTH|EAST|WEST|NE, // 'f'
    TOP| RIGHTBOTTOM| LEFTBOTTOM|LEFTTOP|EAST|BOTTOM , // 'g'
     RIGHTBOTTOM| LEFTBOTTOM|LEFTTOP|EAST|WEST, // 'h'
    SOUTH, // 'i'
     RIGHTBOTTOM|RIGHTTOP|SE, // 'j'
    NORTH|SOUTH|NE|SE, // 'k'
     RIGHTBOTTOM|RIGHTTOP , // 'l'
     RIGHTBOTTOM|LEFTBOTTOM|EAST|WEST|SOUTH, // 'm'
    EAST|SOUTH|RIGHTBOTTOM, //'n' 
    RIGHTBOTTOM|LEFTBOTTOM|EAST|WEST|BOTTOM , //'o' 
    LEFTBOTTOM|LEFTTOP|WEST| NW, //'p' 
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|BOTTOM |SE, // 'Q'
    SOUTH|EAST, // 'r'
    TOP| RIGHTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM , //'s' 
    EAST|WEST|SOUTH, // 't'
     RIGHTBOTTOM| LEFTBOTTOM|BOTTOM , // 'u' 
     LEFTBOTTOM|SW, // 'v' 
     RIGHTBOTTOM| LEFTBOTTOM|BOTTOM|SOUTH, // 'w' 
     NW|SW|NE|SE, // 'x' 
     LEFTBOTTOM|LEFTTOP|EAST|BOTTOM | NORTH, // 'y'
    WEST|BOTTOM |SW, // 'z'
    WEST|NE|SE, // 123 '{' 
    NORTH|SOUTH, // 124 '|' 
    EAST|NW|SW, // 125 '}' 
     RIGHTBOTTOM|LEFTTOP|EAST|WEST, // 126 '~'
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE|NORTH|SOUTH, // 127 ALL ON 
    NORTH, // 128 NORTH 
    NE, // 129 NE 
    EAST, // 130 EAST
    SE, // 131 SE
    SOUTH, //  132 SOUTH
    SW, // 133 SW
    WEST, // 134 EAST
    NW, // 135 NW
    SW|WEST, //136  GAUGE 2 (use space for GAUGE 0, SW for GAUGE 1)
    SW|WEST|NW|NORTH, //137 GAUGE 4 (use EAST ARROW for GAUGE 3)
    SW|WEST|NW|NORTH|NE, //138 GAUGE 5 (use EAST ARROW for GAUGE 3)
    SW|WEST|NW|NORTH|NE|EAST, //139 GAUGE 6 (use EAST ARROW for GAUGE 3)
    SW|WEST|NW|NORTH|NE|EAST|SE, //140 GAUGE 7
    SW|WEST|NW|NORTH|NE|EAST|SE|SOUTH|BOTTOM, //141 GAUGE 9 (use '*' for GAUGE 8)
    SW|WEST|NW|NORTH|NE|EAST|SE|SOUTH|BOTTOM|LEFTBOTTOM, //142 GAUGE 10 
    SW|WEST|NW|NORTH|NE|EAST|SE|SOUTH|BOTTOM|LEFTBOTTOM|LEFTTOP, //143 GAUGE 11 
    SW|WEST|NW|NORTH|NE|EAST|SE|SOUTH|BOTTOM|LEFTBOTTOM|LEFTTOP|TOP, //144 GAUGE 12 
    SW|WEST|NW|NORTH|NE|EAST|SE|SOUTH|BOTTOM|LEFTBOTTOM|LEFTTOP|TOP|RIGHTTOP, 
     //145 GAUGE 13  use 128 for GAUGE 14
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 160
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 176
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 192
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 208
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 224
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 240
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE, // 8
    TOP| RIGHTBOTTOM|RIGHTTOP| LEFTBOTTOM|LEFTTOP|EAST|WEST|BOTTOM | NW|SW|NE|SE // 255
};

#define SWAPSEG(_a,_b) { if (tp2.phoneled.temp16.u & _a) { \
tp2.generic.buffer |= _b;} \
if (tp2.phoneled.temp16.u & _b) { tp2.generic.buffer |= _a;} }
void rotate_alpha_font()
{
        tp2.generic.buffer = 0;
        SWAPSEG(TOP,BOTTOM);
        SWAPSEG(NORTH,SOUTH);
        SWAPSEG(LEFTTOP,RIGHTBOTTOM);
        SWAPSEG(LEFTBOTTOM,RIGHTTOP);
        SWAPSEG(EAST,WEST);
        SWAPSEG(NW,SE);
        SWAPSEG(SW,NE);
        tp2.phoneled.temp16.u = tp2.generic.buffer;
}
#undef SWAPSEG
#undef TOP 
#undef RIGHTTOP 
#undef RIGHTBOTTOM 
#undef BOTTOM 
#undef LEFTBOTTOM 
#undef LEFTTOP 
#undef NORTH 
#undef NE 
#undef EAST 
#undef SE 
#undef SOUTH 
#undef SW 
#undef WEST 
#undef NW 


#define TOP 0x80
#define RIGHTTOP 0x40
#define RIGHTBOTTOM 0x20
#define BOTTOM 0x10
#define LEFTBOTTOM 0x08
#define LEFTTOP 0x04
#define CENTER 0x02


#define SWAPSEG(_a,_b) { if (tp2.phoneled.temp8 & _a) \
{ tp2.phoneled.temp16.bytes.lowbyte |= _b;}\
 if (tp2.phoneled.temp8 & _b) { \
tp2.phoneled.temp16.bytes.lowbyte |= _a;} }

void rotate_sevenseg_font()
{
        tp2.phoneled.temp16.bytes.lowbyte = 0;
        SWAPSEG(TOP,BOTTOM);
        SWAPSEG(LEFTTOP,RIGHTBOTTOM);
        SWAPSEG(RIGHTTOP,LEFTBOTTOM);
        if (tp2.phoneled.temp8 & CENTER)
        {
                tp2.phoneled.temp16.bytes.lowbyte |= CENTER;
        }
        tp2.phoneled.temp8 = tp2.phoneled.temp16.bytes.lowbyte;
}
#undef SWAPSEG

rom const uint8 sevenseg_font[] ={
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP,// 0
     RIGHTTOP|RIGHTBOTTOM,// 1
     TOP|RIGHTTOP|BOTTOM|LEFTBOTTOM|CENTER,// 2
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|CENTER,// 3
     RIGHTTOP|RIGHTBOTTOM|LEFTTOP|CENTER,// 4
     TOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,// 5
     TOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 6
     TOP|RIGHTTOP|RIGHTBOTTOM,// 7
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,// 9
     TOP|RIGHTTOP|RIGHTBOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 10 'A'
     RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 11 'B'
     TOP|BOTTOM|LEFTBOTTOM|LEFTTOP,//12 'C' 
     RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|CENTER,// 13 'D'
     TOP|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 14 'E'
     TOP|LEFTBOTTOM|LEFTTOP|CENTER,// 15 'F'
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 16
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 32
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP,// '0'  48
     RIGHTTOP|RIGHTBOTTOM,// 1
     TOP|RIGHTTOP|BOTTOM|LEFTBOTTOM|CENTER,// 2
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|CENTER,// 3
     RIGHTTOP|RIGHTBOTTOM|LEFTTOP|CENTER,// 4
     TOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,// 5
     TOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 6
     TOP|RIGHTTOP|RIGHTBOTTOM,// 7
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,// 9
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 64
     TOP|RIGHTTOP|RIGHTBOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'A'
     RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'B'
     TOP|BOTTOM|LEFTBOTTOM|LEFTTOP,//'C' 
     RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|CENTER,// 'D'
     TOP|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'E'
     TOP|LEFTBOTTOM|LEFTTOP|CENTER,// 'F'
     TOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'G'
     RIGHTTOP|RIGHTBOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'H'
     LEFTBOTTOM|LEFTTOP,// 'I'
     RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM,// 'J'
     RIGHTTOP|RIGHTBOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'K'
     BOTTOM|LEFTBOTTOM|LEFTTOP,// 'L'
     RIGHTBOTTOM|LEFTBOTTOM|CENTER,// 'M'
     RIGHTBOTTOM|LEFTBOTTOM|CENTER,// 'N'
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP,// 'O'
     TOP|RIGHTTOP|LEFTBOTTOM|LEFTTOP|CENTER,// 80 'P'
     TOP|RIGHTTOP|RIGHTBOTTOM|LEFTTOP|CENTER,// 'Q'
     LEFTBOTTOM|CENTER,// 'R' 
     TOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,// 'S'
     BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,//'T' 
     RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP,// 'U'
     RIGHTBOTTOM|BOTTOM|LEFTBOTTOM,//'V' 
     RIGHTBOTTOM|BOTTOM|LEFTBOTTOM,// 'W'
     RIGHTTOP|RIGHTBOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 'X'
     RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTTOP|CENTER,//'Y'
     TOP|RIGHTTOP|BOTTOM|LEFTBOTTOM|CENTER,// 'Z'
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 96
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 112
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 128
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 144
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 160
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 176
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 192
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 208
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 224
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 240
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 8
     TOP|RIGHTTOP|RIGHTBOTTOM|BOTTOM|LEFTBOTTOM|LEFTTOP|CENTER,// 255
};
#undef TOP 
#undef RIGHTTOP 
#undef RIGHTBOTTOM 
#undef BOTTOM 
#undef LEFTBOTTOM 
#undef LEFTTOP 
#undef CENTER

 

Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.