Yoshiyuki Uehara / Mbed 2 deprecated Maple

Dependencies:   mbed

Revision:
3:eec13a411e94
Parent:
2:299a1c9a5795
--- a/Maple_OLED.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_OLED.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -1,13 +1,1771 @@
-//copyright 2011 Uehara Yoshiyuki
-//====================================================================
-//The author provide the programs without any guarantees or warranty.
-//The author is not responsible for any damage or losses of any kind 
-//caused by using or misusing of the programs.
-//The author is under no obligation to provide support, service, 
-//corrections, or upgrades to the programs.
-//====================================================================
-// MAPLE board[MARM01-BASE]
-// OLED() driver
-#include "Maple_OLED.h"
-#include "Maple.h"
-#include "mbed.h"
+//copyright 2011 Uehara Yoshiyuki
+//====================================================================
+//The author provide the programs without any guarantees or warranty.
+//The author is not responsible for any damage or losses of any kind 
+//caused by using or misusing of the programs.
+//The author is under no obligation to provide support, service, 
+//corrections, or upgrades to the programs.
+//====================================================================
+// MAPLE board[MARM01-BASE]
+// OLED(UG-2828GDEDF11, SSD1351) driver
+#include "Maple_OLED.h"
+#include "Maple.h"
+#include "mbed.h"
+
+// create SPI for OLED in SLOT-1/2 of MARM01-BASE
+//   3-wire SPI and power-control, reset-control
+SPI OLED_spi(p5, p6, p7);       // mosi, miso, sclk for SLOT-1/2 
+DigitalOut OLED_cs1(p8);        // cs       for SLOT-1
+DigitalOut OLED_power1(p11);    // power-on for SLOT-1(GPIO2)
+DigitalOut OLED_reset1(p30);    // reset    for SLOT-1(GPIO4)
+DigitalOut OLED_cs2(p26);       // cs       for SLOT-2
+DigitalOut OLED_power2(p17);    // power-on for SLOT-2(GPIO2)
+DigitalOut OLED_reset2(p21);    // reset    for SLOT-2(GPIO4)
+
+// global variables
+int OLED_color_a1;  // foreground color a
+int OLED_color_b1;  // foreground color b
+int OLED_color_c1;  // forebround color c
+int OLED_color_a2;  // background color a
+int OLED_color_b2;  // background color b
+int OLED_color_c2;  // background color c
+int OLED_cursor_x;  // cursor position x (column-left)
+int OLED_cursor_y;  // cursor position y (row-upper)
+
+// assert cs for the OLED selected
+//  slot: 1..SLOT-1, 2..SLOT-2
+void OLED_cs_assert(int slot) {
+    switch(slot){
+    case 1: OLED_cs1 = CS_ASSERT;  break;
+    case 2: OLED_cs2 = CS_ASSERT;  break;
+    }
+}
+
+// negate cs for all OLEDs
+void OLED_cs_negate() {
+    OLED_cs1 = CS_NEGATE;
+    OLED_cs2 = CS_NEGATE;
+}
+
+// OLED set column address
+//  a: start address (0x00-0x7f, 0x00 by reset)
+//  b: end address   (0x00-0x7f, 0x7f by reset)
+void OLED_set_column_address(int a, int b) {
+    OLED_spi.write(0x15);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+}
+
+// OLED set row address
+//  a: start address (0x00-0x7f, 0x00 by reset)
+//  b: end address   (0x00-0x7f, 0x7f by reset)
+void OLED_set_row_address(int a, int b) {
+    OLED_spi.write(0x75);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+}
+
+// OLED write RAM
+void OLED_write_ram_command() {
+    OLED_spi.write(0x5c);
+}
+
+// OLED read RAM .. not supported by SPI
+void OLED_read_ram_command() {
+    OLED_spi.write(0x5d);
+}
+
+// OLED set re-map/color depth
+//   a(0): 0..horizontal address increment  1..vertical address increment    (0 by reset) 
+//   a(1): 0..column address 0 is to SEG0   1..column address 127 is to SEG0 (0 by reset)
+//   a(2): 0..color sequence A->B->C        1..color sequence C->B->A        (0 by reset)
+//   a(3): 0..reserved                      1..reserved
+//   a(4): 0..scan COM(0)->COM(N-1)         1..scan COM(N-1)->COM(0)         (0 by reset)
+//   a(5): 0..disable COM split odd even    1..enable COM split odd even     (1 by reset)
+//   a(7-6): 00..65k color
+//           01..65k color (reset)
+//           10..262k color
+//           11..262k color 16-bit format 2
+void OLED_set_remap_color_depth(int a) {
+    OLED_spi.write(0xa0);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display start line
+//  a: start line (0x00-0x7f, 0x00 by reset)
+void OLED_set_display_start_line(int a) {
+    OLED_spi.write(0xa1);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display offset
+//  a: offset (0x00-0x7f, 0x60 by reset)
+void OLED_set_display_offset(int a) {
+    OLED_spi.write(0xa2);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display mode all off
+void OLED_set_display_mode_all_off() {
+    OLED_spi.write(0xa4);
+}
+
+// OLED set display mode all on
+void OLED_set_display_mode_all_on() {
+    OLED_spi.write(0xa5);
+}
+
+// OLED set display mode reset to normal display (reset)
+void OLED_set_display_mode_normal() {
+    OLED_spi.write(0xa6);
+}
+
+// OLED set display mode reset to inverse display
+void OLED_set_display_mode_inverse() {
+    OLED_spi.write(0xa7);
+}
+
+// OLED function selection
+//  a(0): 0..select external VDD  1..enable internal regulator (1 by reset)
+//  a(7-6): 00..select  8-bit parallel interface (reset)
+//          01..select 16-bit parallel interface
+//          11..select 18-bit parallel interface
+void OLED_function_selection(int a) {
+    OLED_spi.write(0xab);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED no operation
+void OLED_no_operation_ad() {
+    OLED_spi.write(0xad);
+}
+
+// OLED set sleep mode on
+void OLED_set_sleep_mode_on() {
+    OLED_spi.write(0xae);
+}
+
+// OLED set sleep mode off
+void OLED_set_sleep_mode_off() {
+    OLED_spi.write(0xaf);
+}
+
+// OLED no operation
+void OLED_no_operation_b0() {
+    OLED_spi.write(0xb0);
+}
+
+// OLED set reset / pre-charge period
+//  a(3-0): phase 1 period (0x2..0xf, 0x2 by reset)
+//  a(7-4): phase 2 period (0x3..0xf, 0x8 by reset)
+void OLED_set_reset_pre_charge_period(int a) {
+    OLED_spi.write(0xb1);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED display enhancement
+//  a, b, c: 0x00, 0x00, 0x00..normal (reset)
+//           0xa4, 0x00, 0x00..enhance display
+void OLED_display_enhancement(int a, int b, int c) {
+    OLED_spi.write(0xb2);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+}
+
+// OLED front clock divider / oscillator frequency
+//  a(3-0): divset (0x0-0xa, 0x1 by reset)
+//  a(7-4): oscillator frequency (0xd by reset)
+void OLED_front_clock_divider_oscillator_frequency(int a) {
+    OLED_spi.write(0xb3);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set segment low voltage
+void OLED_set_segment_low_voltage() {
+    OLED_spi.write(0xb4);
+    OLED_spi.write(0x1a0);
+    OLED_spi.write(0x1b5);
+    OLED_spi.write(0x155);
+}
+
+// OLED set GPIO
+//  a(1-0): GPIO0
+//  a(3-2): GPIO1
+//    00..pin Hi-Z, input disabled
+//    01..pin Hi-Z, input enabled
+//    10..pin output low (reset)
+//    11..pin output high
+void OLED_set_GPIO(int a) {
+    OLED_spi.write(0xb5);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set second pre-charge period
+//  a(3-0): period (0x1-0xf, 0x8 by reset)
+void OLED_set_second_pre_charge_period(int a) {
+    OLED_spi.write(0xb6);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED look up table for gray scale pulse width
+void OLED_look_up_table_for_gray_scale_pulse_width() {
+    const int a[63] = {
+        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+        0x12, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2a, 0x2d, 0x30, 0x33,
+        0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c,
+        0x70, 0x74, 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91, 0x96, 0x9b, 0xa0, 0xa5, 0xaa, 0xaf, 0xb4
+    };
+
+    OLED_spi.write(0xb8);
+    for(int i = 0; i < 63; ++i) {
+        OLED_spi.write(0x100 | a[i]);
+    }
+}
+
+// OLED use built-in linear look up table (linear by reset)
+void OLED_use_built_in_linear_lut() {
+    OLED_spi.write(0xb9);
+}
+
+// OLED set pre-charge voltage
+//  a: 0x00-0x1f (0x17 by reset)
+void OLED_set_pre_charge_voltage(int a) {
+    OLED_spi.write(0xbb);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set VCOMH_voltage
+//  a: 0x00-0x07 (0x05 by reset)
+void OLED_set_vcomh_voltage(int a) {
+    OLED_spi.write(0xbe);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set contrast current for color A, B, C
+//  a: contrast value for color A (0x8a by reset)
+//  b: contrast value for color B (0x51 by reset)
+//  c: contrast value for color C (0x8a by reset)
+void OLED_set_contrast_for_color_abc(int a, int b, int c) {
+    OLED_spi.write(0xc1);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+}
+
+// OLED master contrast current control
+//  a: 0x00-0x0e..reduce output current for all colors
+//          0x0f..no change (reset)
+void OLED_master_contrast_current_control(int a) {
+    OLED_spi.write(0xc7);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set MUX ratio
+//  a: 0x0f-0x7f..16MUX-128MUX (0x7f by reset)
+void OLED_set_mux_ratio(int a) {
+    OLED_spi.write(0xca);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED no operation
+void OLED_no_operation_d1() {
+    OLED_spi.write(0xd1);
+}
+
+// OLED no operation
+void OLED_no_operation_e3() {
+    OLED_spi.write(0xe3);
+}
+
+// OLED set command lock
+//  a: MCU protection status
+//    0x12..unlock OLED driver IC MCU interface from entering command (reset)
+//    0x16..Lock OLED driver IC MCU interface from entering command
+//    0xb0..command a2, b1, b3, bb, be, c1 inaccessible in both lock and unlock state (reset)
+//    0xb1..command a2, b1, b3, bb, be, c1 accessible if in unlock state
+void OLED_set_command_lock(int a) {
+    OLED_spi.write(0xfd);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED horizontal scroll
+//  a: 0x00     ..no scrolling
+//     0x01-0x3f..scroll towards SEG127 with 1 column offset
+//     0x40-0xff..scroll towards SEG0   with 1 column offset
+//  b: 0x00-0x7f..start row address
+//  c: 0x00-0xff..number of rows to be h-scrolled  (b + c <= 0x80)
+//  d: reserved (0x00 by reset)
+//  e: scrolling time interval
+//      0x00..test mode
+//      0x01..normal
+//      0x02..slow
+//      0x03..slowest
+void OLED_horizontal_scroll(int a, int b, int c, int d, int e) {
+    OLED_spi.write(0x96);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+    OLED_spi.write(0x100 | d);
+    OLED_spi.write(0x100 | e);
+}
+
+// OLED stop horizontal scroll
+void OLED_stop_moving() {
+    OLED_spi.write(0x9e);
+}
+
+// OLED start horizontal scroll
+void OLED_start_moving() {
+    OLED_spi.write(0x9f);
+}
+
+// OLED initialize
+void OLED_initialize() {
+    OLED_power1 = OLED_POWER_OFF;
+    OLED_power2 = OLED_POWER_OFF;
+
+    OLED_cs_negate();   
+    OLED_spi.format(9, 3);          // 9bit mode, CPOL=1(inactive-H), CPHA=1(edge-UP)
+    OLED_spi.frequency(20000000);   // 20MHz (50ns)
+
+    OLED_reset1 = OLED_RESET_ON;
+    OLED_reset2 = OLED_RESET_ON;
+    wait_us(10);
+    OLED_reset1 = OLED_RESET_OFF;
+    OLED_reset2 = OLED_RESET_OFF;
+
+    OLED_set_color(0, 0, 0, 0);             // background color
+    OLED_set_color(1, 0x3f, 0x3f, 0x3f);    // foreground color
+    OLED_set_cursor(0, 0);
+
+    OLED_cs_assert(1);              // SLOT-1
+    OLED_initialize_sub();
+    OLED_cs_negate();
+
+    OLED_cs_assert(2);              // SLOT-2
+    OLED_initialize_sub();
+    OLED_cs_negate();
+
+    OLED_power1 = OLED_POWER_ON;
+    OLED_power2 = OLED_POWER_ON;
+    wait_ms(200);
+}
+
+// OLED initialize sub-program
+//  slot: 1..SLOT-1, 2..SLOT-2
+static void OLED_initialize_sub() {
+    OLED_set_command_lock(0x12);
+    OLED_set_command_lock(0xb1);
+    OLED_set_sleep_mode_on();
+    OLED_front_clock_divider_oscillator_frequency(0xf1);
+    OLED_set_mux_ratio(0x7f);
+    OLED_set_display_offset(0x00);
+    OLED_set_display_start_line(0x00);
+    OLED_set_remap_color_depth(0xb4);   // 262k(18bit) color format-1 
+    OLED_set_GPIO(0x00);
+    OLED_function_selection(0x01);
+    OLED_set_segment_low_voltage();
+    OLED_set_contrast_for_color_abc(0xc8, 0x80, 0xc8);
+    OLED_master_contrast_current_control(0x0f);
+    OLED_look_up_table_for_gray_scale_pulse_width();
+    OLED_set_reset_pre_charge_period(0x32);
+    OLED_display_enhancement(0xa4, 0x00, 0x00);
+    OLED_set_pre_charge_voltage(0x17);    
+    OLED_set_second_pre_charge_period(0x01);
+    OLED_set_vcomh_voltage(0x05);
+    OLED_set_display_mode_normal();
+    OLED_clear_screen(0);               // by background color
+    OLED_set_sleep_mode_off();
+}
+
+// OLED set color
+//  mode: 0..backgound, else..foreground
+void OLED_set_color(int mode, int a, int b, int c) {
+    if(mode == 0) {
+        OLED_color_a2 = a;
+        OLED_color_b2 = b;
+        OLED_color_c2 = c;
+    }
+    else {
+        OLED_color_a1 = a;
+        OLED_color_b1 = b;
+        OLED_color_c1 = c;
+    }
+}
+
+// OLED set print position
+void OLED_set_cursor(int x, int y) {
+    OLED_cursor_x = x;
+    OLED_cursor_y = y;
+}
+
+// OLED clear screen = fill-out with a color
+//  mode: 0..backgound, else..foreground
+void OLED_clear_screen(int mode) {
+    OLED_fill_rectangle(mode, 0, OLED_COLUMN_MAX + 1, 0, OLED_ROW_MAX + 1);
+}
+
+// OLED fill rectangle
+//  mode: 0..backgound, else..foreground
+//  cs: column-start  (0x00..OLED_COLUMN_MAX)
+//  cl: column-length (0x01..OLED_COLUMN_MAX+1)
+//  rs: row-start     (0x00..OLED_ROW_MAX)
+//  rl: row-length    (0x01..OLED_ROW_MAX+1)
+void OLED_fill_rectangle(int mode, int cs, int cl, int rs, int rl) {
+    OLED_set_column_address(cs, cs + cl - 1);
+    OLED_set_row_address(rs, rs + rl - 1);
+    OLED_write_ram_command();
+    for(int i = 0; i < cl * rl; ++i) {
+        OLED_write_pixel(mode);
+    }
+}
+
+// OLED write a pixel in 18-bit color mode
+//  mode: 0..backgound, else..foreground
+void OLED_write_pixel(int mode) {
+    if(mode == 0) {
+        OLED_spi.write(0x100 | OLED_color_a2);
+        OLED_spi.write(0x100 | OLED_color_b2);
+        OLED_spi.write(0x100 | OLED_color_c2);
+    }
+    else {
+        OLED_spi.write(0x100 | OLED_color_a1);
+        OLED_spi.write(0x100 | OLED_color_b1);
+        OLED_spi.write(0x100 | OLED_color_c1);
+    }
+}
+
+// OLED print string
+void OLED_print_string(char s[]) {
+    for(int i = 0; s[i] != '\0'; ++i) {
+        OLED_print_character(s[i]);
+    }
+}
+
+// OLED print integer(1 byte) in hex format
+void OLED_print_hex(int i) {
+    OLED_print_character(int_to_hex1(i >> 4));
+    OLED_print_character(int_to_hex1(i));
+}
+
+// OLED print character of 6*9 font
+//  ch: character
+void OLED_print_character(char ch) {
+static char font[0x80][OLED_FONT_SIZE_Y] = {
+        { 0x90, //  1--1----  0x00 NUL
+          0xd0, //  11-1----
+          0xb0, //  1-11----
+          0x90, //  1--1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x01 SOH
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x02 STX
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x10, //  ---1----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x03 ETX
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x28, //  --1-1---
+          0x10, //  ---1----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x04 EOT
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x05 ENQ
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x48, //  -1--1---
+          0x58, //  -1-11---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x06 ACK
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0xa0, //  1-1-----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x07 BEL
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x08 BS
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xb8, //  1-111---
+          0xe0, //  111-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x09 HT
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0xa0, //  1-1-----
+          0xb8, //  1-111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x0a LF
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x0b VT
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0x40, //  -1------
+          0x38, //  --111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x0c FF
+          0x80, //  1-------
+          0xe0, //  111-----
+          0xb8, //  1-111---
+          0xa0, //  1-1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0d CR
+          0x80, //  1-------
+          0x80, //  1-------
+          0xb0, //  1-11----
+          0x68, //  -11-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0e SO
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0f SI
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x10, //  ---1----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x10 DLE
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x11 DC1
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x12 DC2
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x13 DC3
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x14 DC4
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x00, //  --------
+        },
+        { 0x90, //  1--1----  0x15 NAK
+          0xd0, //  11-1----
+          0xb0, //  1-11----
+          0x90, //  1--1----
+          0x90, //  1--1----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x16 SYN
+          0x80, //  1-------
+          0x40, //  -1------
+          0x28, //  --1-----
+          0xc8, //  11--1---
+          0x68, //  -11-1---
+          0x58, //  -1-11---
+          0x48, //  -1--1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x17 ETB
+          0x80, //  1-------
+          0xe0, //  111-----
+          0xb0, //  1-11----
+          0xe8, //  111-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x18 CAN
+          0x80, //  1-------
+          0x80, //  1-------
+          0x60, //  -11-----
+          0x48, //  -1--1---
+          0x68, //  -11-1---
+          0x58, //  -1-11---
+          0x48, //  -1--1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x19 EM
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x88, //  1---1---
+          0xd8, //  11-11---
+          0xa8, //  1-1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x1a SUB
+          0x80, //  1-------
+          0x40, //  -1------
+          0x30, //  --11----
+          0xe8, //  111-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x1b ESC
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x18, //  ---11---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x1c FS
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x98, //  1--11---
+          0xa0, //  1-1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x1d GS
+          0x80, //  1-------
+          0xb0, //  1-11----
+          0x98, //  1--11---
+          0x60, //  -11-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x1e RS
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xb8, //  1-111---
+          0xa0, //  1-1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x1f US
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0x18, //  ---11---
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x20 space
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x21 !
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x50, //  -1-1----  0x22 "
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x50, //  -1-1----  0x23 #
+          0x50, //  -1-1----
+          0xf8, //  11111---
+          0x50, //  -1-1----
+          0xf8, //  11111---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x24 $
+          0x78, //  -1111---
+          0xa0, //  1-1-----
+          0x70, //  -111----
+          0x28, //  --1-1---
+          0xf0, //  1111----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x25 %
+          0xc8, //  11--1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x98, //  1--11---
+          0x18, //  ---11---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x26 &
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0x40, //  -1------
+          0xa8, //  1-1-1---
+          0x90, //  1--1----
+          0x68, //  -11-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x27 '
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x10, //  ---1----  0x28 (
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x29 )
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2a *
+          0x20, //  --1-----
+          0xa8, //  1-1-1---
+          0x70, //  -111----
+          0xa8, //  1-1-1---
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2b +
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2c ,
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2d -
+          0x00, //  --------
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2e .
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x60, //  -11-----
+          0x60, //  -11-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2f /
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x30 0
+          0x88, //  1---1---
+          0x98, //  1--11---
+          0xa8, //  1-1-1---
+          0xc8, //  11--1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x31 1
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x32 2
+          0x88, //  1---1---
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x33 3
+          0x88, //  1---1---
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x10, //  ---1----  0x34 4
+          0x30, //  --11----
+          0x50, //  -1-1----
+          0x90, //  1--1----
+          0xf8, //  11111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x35 5
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x36 6
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x37 7
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x38 8
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x39 9
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3a :
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3b ;
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x30, //  --11----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x08, //  ----1---  0x3c <
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3d =
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x3e >
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x3f ?
+          0x88, //  1---1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x40 @
+          0x88, //  1---1---
+          0x98, //  1--11---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x98, //  1--11---
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x41 A
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x42 B
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x70, //  -111----
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x43 C
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x44 D
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x45 E
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x46 F
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x47 G
+          0x80, //  1-------
+          0x80, //  1-------
+          0xb8, //  1-111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x48 H
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x49 I
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x38, //  --111---  0x4a J
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0xe0, //  111-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4b K
+          0x90, //  1--1----
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xa0, //  1-1-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x4c L
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4d M
+          0xd8, //  11-11---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4e N
+          0x88, //  1---1---
+          0xc8, //  11--1---
+          0xa8, //  1-1-1---
+          0x98, //  1--11---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x4f O
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x50 P
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x51 Q
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0x90, //  1--1----
+          0x68, //  -11-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x52 R
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0xa0, //  1-1-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x53 S
+          0x80, //  1-------
+          0x80, //  1-------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x54 T
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x55 U
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x56 V
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x57 W
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x58 X
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x59 Y
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x5a Z
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x5b [
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x5c back slash
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x5d ]
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x5e ^
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x5f _
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x60 `
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x61 a
+          0x00, //  --------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x62 b
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x63 c
+          0x00, //  --------
+          0x78, //  -1111---
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x08, //  ----1---  0x64 d
+          0x08, //  ----1---
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x65 e
+          0x00, //  --------
+          0x70, //  -111----
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x18, //  ---11---  0x66 f
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x67 g
+          0x00, //  --------
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x08, //  ----1---
+          0x70, //  -111----
+        },
+        { 0x80, //  1-------  0x68 h
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x69 i
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x6a j
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+        },
+        { 0x80, //  1-------  0x6b k
+          0x80, //  1-------
+          0x88, //  1---1---
+          0x90, //  1--1----
+          0xe0, //  111-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x6c l
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6d m
+          0x00, //  --------
+          0xd0, //  11-1----
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6e n
+          0x00, //  --------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6f o
+          0x00, //  --------
+          0x70, //  -111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x70 p
+          0x00, //  --------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+        },
+        { 0x00, //  --------  0x71 q
+          0x00, //  --------
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x08, //  ----1---
+          0x08, //  ----1---
+        },
+        { 0x00, //  --------  0x72 r
+          0x00, //  --------
+          0x98, //  1--11---
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x73 s
+          0x00, //  --------
+          0x78, //  -1111---
+          0x80, //  1-------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x74 t
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x18, //  ---11---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x75 u
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x76 v
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x77 w
+          0x00, //  --------
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x78 x
+          0x00, //  --------
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x79 y
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+        },
+        { 0x00, //  --------  0x7a z
+          0x00, //  --------
+          0xf8, //  11111---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x7b {
+          0x40, //  -1------
+          0x40, //  -1------
+          0x80, //  1-------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x30, //  --11----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x7c |
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x7d }
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x60, //  -11-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x7e ~
+          0xa8, //  1-1-1---
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x7f DEL
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+    };
+
+    switch(ch) {
+    case 0x0a:  // LF
+        OLED_cursor_y += OLED_FONT_SIZE_Y;
+        if(OLED_cursor_y > OLED_ROW_MAX - OLED_FONT_SIZE_Y) {
+            OLED_cursor_y = 0;
+        }
+        break;
+
+    case 0x0d:  // CR
+        OLED_cursor_x = 0;
+        break;
+
+    default:
+        // print a font
+        OLED_set_column_address(OLED_cursor_x, OLED_cursor_x + OLED_FONT_SIZE_X - 1);
+        OLED_set_row_address(OLED_cursor_y, OLED_cursor_y + OLED_FONT_SIZE_Y - 1);
+        OLED_write_ram_command();
+        for(int i = 0; i < OLED_FONT_SIZE_Y; ++i) {
+            for(int j = 0x80; j > (0x80 >> OLED_FONT_SIZE_X); j >>= 1) {
+                OLED_write_pixel(font[ch][i] & j);
+            }
+        }
+        // increment cursor position
+        OLED_cursor_x += OLED_FONT_SIZE_X;
+        if(OLED_cursor_x > OLED_COLUMN_MAX - OLED_FONT_SIZE_X) {
+            OLED_cursor_x = 0;
+            OLED_cursor_y += OLED_FONT_SIZE_Y;
+            if(OLED_cursor_y > OLED_ROW_MAX - OLED_FONT_SIZE_Y) {
+                OLED_cursor_y = 0;
+            }
+        }
+    }
+
+}