#include #include #include #include #include #include #include #define GLFW_INCLUDE_GLCOREARB #include #include #include "interface.h" using namespace std; namespace APPLE2Einterface { chrono::time_point start_time; DisplayMode display_mode = TEXT; int display_page = 0; // Apple //e page minus 1 (so 0,1 not 1,2) bool mixed_mode = false; extern int font_offset; extern unsigned char font_bytes[96 * 7 * 8]; static int gWindowWidth; static int gWindowHeight; bool gPrintShaderLog = true; // to handle https://github.com/glfw/glfw/issues/161 static double gMotionReported = false; static double gOldMouseX, gOldMouseY; static int gButtonPressed = -1; deque event_queue; bool event_waiting() { return event_queue.size() > 0; } event dequeue_event() { if(event_waiting()) { event e = event_queue.front(); event_queue.pop_front(); return e; } else return {NONE, 0}; } using namespace std; float aspectRatio = 1; GLuint font_texture; GLuint font_texture_location; const int fonttexture_w = 7; const int fonttexture_h = 8 * 96; GLuint textport_texture[2]; GLuint textport_texture_location; GLuint blink_location; GLuint lores_texture_location; const int textport_w = 40; const int textport_h = 24; GLuint hires_texture[2]; GLuint hires_texture_location; const int hires_w = 320; // MSBit is color chooser, Apple ][ weirdness const int hires_h = 192; #if 0 struct button { int string_texture; string content; button(const string& content_) : content(content_) { // construct string texture } tuple get_dimensions() { int w = content.size() * 7 + 3 * 2; int h = 8 + 3 * 2; } void draw() { // draw lines 2 pixels around // draw lines 1 pixels around // blank area 0 pixels around // draw string } }; struct buttons { } #endif static void CheckOpenGL(const char *filename, int line) { int glerr; if((glerr = glGetError()) != GL_NO_ERROR) { printf("GL Error: %04X at %s:%d\n", glerr, filename, line); } } GLuint upper_screen_area; GLuint lower_screen_area; const int raster_coords_attrib = 0; static bool CheckShaderCompile(GLuint shader, const std::string& shader_name) { int status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(status == GL_TRUE) return true; if(gPrintShaderLog) { int length; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); if (length > 0) { char log[length]; glGetShaderInfoLog(shader, length, NULL, log); fprintf(stderr, "%s shader error log:\n%s\n", shader_name.c_str(), log); } fprintf(stderr, "%s compile failure.\n", shader_name.c_str()); fprintf(stderr, "shader text:\n"); glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); char source[length]; glGetShaderSource(shader, length, NULL, source); fprintf(stderr, "%s\n", source); } return false; } static bool CheckProgramLink(GLuint program) { int status; glGetProgramiv(program, GL_LINK_STATUS, &status); if(status == GL_TRUE) return true; if(gPrintShaderLog) { int log_length; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); if (log_length > 0) { char log[log_length]; glGetProgramInfoLog(program, log_length, NULL, log); fprintf(stderr, "program error log: %s\n",log); } } return false; } GLuint hires_program; GLuint text_program; GLuint lores_program; static const char *hires_vertex_shader = "\n\ in vec2 vertex_coords;\n\ out vec2 raster_coords;\n\ \n\ void main()\n\ {\n\ vec2 eye_coords = vertex_coords / vec2(280,192) * vec2(2, 2) - vec2(1, 1);\n\ raster_coords = vertex_coords;\n\ gl_Position = vec4(eye_coords * vec2(1, -1), 0.5, 1.0);\n\ }\n"; static const char *text_vertex_shader = "\n\ in vec2 vertex_coords;\n\ out vec2 text_coords;\n\ out vec2 raster_coords;\n\ \n\ void main()\n\ {\n\ vec2 eye_coords = vertex_coords / vec2(280,192) * vec2(2, 2) - vec2(1, 1);\n\ raster_coords = vertex_coords;\n\ text_coords = vec2(int(vertex_coords.x / 7), int(vertex_coords.y / 8));\n\ gl_Position = vec4(eye_coords * vec2(1, -1), 0.5, 1.0);\n\ }\n"; static const char *hires_fragment_shader = "\n\ in vec2 raster_coords;\n\ uniform usampler2DRect hires_texture;\n\ \n\ out vec4 color;\n\ \n\ void main()\n\ {\n\ int byte = int(raster_coords.x) / 7;\n\ int bit = int(raster_coords.x) % 7;\n\ int texturex = byte * 8 + bit;\n\ ivec2 tc = ivec2(texturex, raster_coords.y);\n\ uint pixel = texture(hires_texture, tc).x;\n\ float value = pixel / 255.0;\n\ color = vec4(value, value, value, value);\n\ }\n"; // 0-31 is inverse 32-63 // 32-63 is inverse 0-31 // 64-95 is blink 32-63 // 96-127 is blink 0-31 // 128-159 is normal 32-63 // 160-191 is normal 0-31 // 192-223 is normal 32-63 // 224-255 is normal 64-95 static const char *text_fragment_shader = "\n\ in vec2 raster_coords;\n\ in vec2 text_coords;\n\ uniform int blink;\n\ uniform usampler2DRect font_texture;\n\ uniform usampler2DRect textport_texture;\n\ \n\ out vec4 color;\n\ \n\ void main()\n\ {\n\ uint character;\n\ character = texture(textport_texture, uvec2(uint(raster_coords.x) / 7u, uint(raster_coords.y) / 8u)).x; \n\ bool inverse = false;\n\ if(character >= 0u && character <= 31u) {\n\ character = character - 0u + 32u;\n\ inverse = true;\n\ } else if(character >= 32u && character <= 63u) {\n\ character = character - 32u + 0u;\n\ inverse = true;\n\ } else if(character >= 64u && character <= 95u) {\n\ character = character - 64u + 32u; // XXX BLINK \n\ inverse = blink == 0;\n\ } else if(character >= 96u && character <= 127u){\n\ character = character - 96u + 0u; // XXX BLINK \n\ inverse = blink == 0;\n\ } else if(character >= 128u && character <= 159u)\n\ character = character - 128u + 32u;\n\ else if(character >= 160u && character <= 191u)\n\ character = character - 160u + 0u;\n\ else if(character >= 192u && character <= 223u)\n\ character = character - 192u + 32u;\n\ else if(character >= 224u && character <= 255u)\n\ character = character - 224u + 64u;\n\ else \n\ character = 33u;\n\ uvec2 inglyph = uvec2(uint(raster_coords.x) % 7u, uint(raster_coords.y) % 8u);\n\ uvec2 infont = inglyph + uvec2(0, character * 8u);\n\ uint pixel = texture(font_texture, infont).x;\n\ float value;\n\ if(inverse)\n\ value = 1.0 - pixel / 255.0;\n\ else\n\ value = pixel / 255.0;\n\ color = vec4(value, value, value, value);\n\ // color = vec4(value, float(inglyph.x)/7, float(inglyph.y)/8, value);\n\ // color = vec4(vec2(inglyph) / vec2(7, 8), 0, 1);\n\ // BLINK?? \n\ // INVERSE?? \n\ }\n"; static const char *lores_fragment_shader = "\n\ in vec2 raster_coords;\n\ in vec2 text_coords;\n\ uniform usampler2DRect font_texture;\n\ uniform usampler2DRect lores_texture;\n\ \n\ out vec4 color;\n\ \n\ void main()\n\ {\n\ uint byte;\n\ byte = texture(lores_texture, uvec2(uint(raster_coords.x) / 7u, uint(raster_coords.y) / 8u)).x; \n\ uint inglyph_y = uint(raster_coords.y) % 8u;\n\ uint lorespixel;\n\ if(inglyph_y < 4u)\n\ lorespixel = byte % 16u;\n\ else\n\ lorespixel = byte / 16u;\n\ switch(lorespixel) {\n\ case 0:\n\ color = vec4(0, 0, 0, 1);\n\ break;\n\ case 1:\n\ color = vec4(227.0/255.0, 30.0/255.0, 96.0/255.0, 1);\n\ break;\n\ case 2:\n\ color = vec4(96.0/255.0, 78.0/255.0, 189.0/255.0, 1);\n\ break;\n\ case 3:\n\ color = vec4(255.0/255.0, 68.0/255.0, 253.0/255.0, 1);\n\ break;\n\ case 4:\n\ color = vec4(9.0/255.0, 163.0/255.0, 96.0/255.0, 1);\n\ break;\n\ case 5:\n\ color = vec4(156.0/255.0, 156.0/255.0, 156.0/255.0, 1);\n\ break;\n\ case 6:\n\ color = vec4(20.0/255.0, 207.0/255.0, 253.0/255.0, 1);\n\ break;\n\ case 7:\n\ color = vec4(208.0/255.0, 195.0/255.0, 255.0/255.0, 1);\n\ break;\n\ case 8:\n\ color = vec4(96.0/255.0, 114.0/255.0, 3.0/255.0, 1);\n\ break;\n\ case 9:\n\ color = vec4(255.0/255.0, 106.0/255.0, 60.0/255.0, 1);\n\ break;\n\ case 10:\n\ color = vec4(156.0/255.0, 156.0/255.0, 156.0/255.0, 1);\n\ break;\n\ case 11:\n\ color = vec4(255.0/255.0, 160.0/255.0, 208.0/255.0, 1);\n\ break;\n\ case 12:\n\ color = vec4(20.0/255.0, 245.0/255.0, 60.0/255.0, 1);\n\ break;\n\ case 13:\n\ color = vec4(208.0/255.0, 221.0/255.0, 141.0/255.0, 1);\n\ break;\n\ case 14:\n\ color = vec4(114.0/255.0, 255.0/255.0, 208.0/255.0, 1);\n\ break;\n\ case 15:\n\ color = vec4(255.0/255.0, 255.0/255.0, 255.0/255.0, 1);\n\ break;\n\ }\n\ }\n"; static GLuint GenerateProgram(const string& shader_name, const string& vertex_shader_text, const string& fragment_shader_text) { std::string spec_string; spec_string = "#version 140\n"; // reset line number so that I can view errors with the line number // they have in the base shaders. spec_string += "#line 0\n"; std::string vertex_shader_string = spec_string + vertex_shader_text; std::string fragment_shader_string = spec_string + fragment_shader_text; GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); const char *string = vertex_shader_string.c_str(); glShaderSource(vertex_shader, 1, &string, NULL); glCompileShader(vertex_shader); if(!CheckShaderCompile(vertex_shader, shader_name + " vertex shader")) return 0; GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); string = fragment_shader_string.c_str(); glShaderSource(fragment_shader, 1, &string, NULL); glCompileShader(fragment_shader); if(!CheckShaderCompile(fragment_shader, shader_name + " fragment shader")) return 0; GLuint program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); // XXX Really need to do this generically glBindAttribLocation(program, raster_coords_attrib, "vertex_coords"); CheckOpenGL(__FILE__, __LINE__); glLinkProgram(program); CheckOpenGL(__FILE__, __LINE__); if(!CheckProgramLink(program)) return 0; return program; } GLuint make_rectangle_vertex_array(float x, float y, float w, float h) { GLuint array; glGenVertexArrays(1, &array); glBindVertexArray(array); CheckOpenGL(__FILE__, __LINE__); /* just x, y, also pixel coords */ GLuint vertices; glGenBuffers(1, &vertices); glBindBuffer(GL_ARRAY_BUFFER, vertices); float coords[4][2] = { {x, y}, {x + w, y}, {x, y + h}, {x + w, y + h}, }; glBufferData(GL_ARRAY_BUFFER, sizeof(coords[0]) * 4, coords, GL_STATIC_DRAW); CheckOpenGL(__FILE__, __LINE__); glVertexAttribPointer(raster_coords_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(raster_coords_attrib); CheckOpenGL(__FILE__, __LINE__); return array; } void initialize_screen_areas() { upper_screen_area = make_rectangle_vertex_array(0, 0, 280, 160); lower_screen_area = make_rectangle_vertex_array(0, 160, 280, 32); } GLuint initialize_texture(int w, int h, unsigned char *pixels = NULL) { GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_RECTANGLE, texture); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); CheckOpenGL(__FILE__, __LINE__); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, w, h, 0, GL_RED_INTEGER_EXT, GL_UNSIGNED_BYTE, pixels); CheckOpenGL(__FILE__, __LINE__); return texture; } void initialize_gl(void) { glClearColor(0, 0, 0, 1); CheckOpenGL(__FILE__, __LINE__); font_texture = initialize_texture(fonttexture_w, fonttexture_h, font_bytes); textport_texture[0] = initialize_texture(textport_w, textport_h); textport_texture[1] = initialize_texture(textport_w, textport_h); hires_texture[0] = initialize_texture(hires_w, hires_h); hires_texture[1] = initialize_texture(hires_w, hires_h); CheckOpenGL(__FILE__, __LINE__); hires_program = GenerateProgram("hires", hires_vertex_shader, hires_fragment_shader); hires_texture_location = glGetUniformLocation(hires_program, "hires_texture"); text_program = GenerateProgram("textport", text_vertex_shader, text_fragment_shader); textport_texture_location = glGetUniformLocation(text_program, "textport_texture"); font_texture_location = glGetUniformLocation(text_program, "font_texture"); blink_location = glGetUniformLocation(text_program, "blink"); CheckOpenGL(__FILE__, __LINE__); lores_program = GenerateProgram("textport", text_vertex_shader, lores_fragment_shader); lores_texture_location = glGetUniformLocation(text_program, "lores_texture"); CheckOpenGL(__FILE__, __LINE__); initialize_screen_areas(); CheckOpenGL(__FILE__, __LINE__); } unsigned char textport[2][24][40]; void set_shader(DisplayMode display_mode, bool mixed_mode, int blink) { if(mixed_mode || (display_mode == TEXT)) { glUseProgram(text_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE, textport_texture[display_page]); glUniform1i(textport_texture_location, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_RECTANGLE, font_texture); glUniform1i(font_texture_location, 1); glUniform1i(blink_location, blink); } else if(display_mode == LORES) { glUseProgram(lores_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE, textport_texture[display_page]); glUniform1i(lores_texture_location, 0); } else if(display_mode == HIRES) { glUseProgram(hires_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE, hires_texture[display_page]); glUniform1i(hires_texture_location, 0); } } static void redraw(GLFWwindow *window) { chrono::time_point now; now = std::chrono::system_clock::now(); auto elapsed_millis = chrono::duration_cast(now - start_time).count(); CheckOpenGL(__FILE__, __LINE__); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); set_shader(display_mode, false, (elapsed_millis / 1870) % 2); glBindVertexArray(upper_screen_area); CheckOpenGL(__FILE__, __LINE__); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CheckOpenGL(__FILE__, __LINE__); set_shader(display_mode, mixed_mode, (elapsed_millis / 1870) % 2); glBindVertexArray(lower_screen_area); CheckOpenGL(__FILE__, __LINE__); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CheckOpenGL(__FILE__, __LINE__); } static void error_callback(int error, const char* description) { fprintf(stderr, "GLFW: %s\n", description); } static void key(GLFWwindow *window, int key, int scancode, int action, int mods) { static bool super_down = false; if(action == GLFW_PRESS) { if(key == GLFW_KEY_RIGHT_SUPER) super_down = true; else if(key == GLFW_KEY_V) { const char* text = glfwGetClipboardString(window); if (text) event_queue.push_back({PASTE, 0, strdup(text)}); } else event_queue.push_back({KEYDOWN, key}); } else if(action == GLFW_RELEASE) { if(key == GLFW_KEY_RIGHT_SUPER) super_down = false; event_queue.push_back({KEYUP, key}); } } static void resize(GLFWwindow *window, int x, int y) { glfwGetFramebufferSize(window, &gWindowWidth, &gWindowHeight); glViewport(0, 0, gWindowWidth, gWindowHeight); } static void button(GLFWwindow *window, int b, int action, int mods) { double x, y; glfwGetCursorPos(window, &x, &y); if(b == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) { gButtonPressed = 1; gOldMouseX = x; gOldMouseY = y; } else { gButtonPressed = -1; } } static void motion(GLFWwindow *window, double x, double y) { // to handle https://github.com/glfw/glfw/issues/161 // If no motion has been reported yet, we catch the first motion // reported and store the current location if(!gMotionReported) { gMotionReported = true; gOldMouseX = x; gOldMouseY = y; } double dx, dy; dx = x - gOldMouseX; dy = y - gOldMouseY; gOldMouseX = x; gOldMouseY = y; if(gButtonPressed == 1) { // mouse does nothing } } static void scroll(GLFWwindow *window, double dx, double dy) { } static GLFWwindow* window; const int pixel_scale = 3; void start() { glfwSetErrorCallback(error_callback); start_time = std::chrono::system_clock::now(); if(!glfwInit()) exit(EXIT_FAILURE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_SAMPLES, 4); window = glfwCreateWindow(gWindowWidth = 280 * pixel_scale, gWindowHeight = 192 * pixel_scale, "Apple //e", NULL, NULL); if (!window) { glfwTerminate(); fprintf(stdout, "Couldn't open main window\n"); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); CheckOpenGL(__FILE__, __LINE__); printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); printf("GL_VERSION: %s\n", glGetString(GL_VERSION)); CheckOpenGL(__FILE__, __LINE__); initialize_gl(); CheckOpenGL(__FILE__, __LINE__); glfwSetKeyCallback(window, key); glfwSetMouseButtonCallback(window, button); glfwSetCursorPosCallback(window, motion); glfwSetScrollCallback(window, scroll); glfwSetFramebufferSizeCallback(window, resize); glfwSetWindowRefreshCallback(window, redraw); CheckOpenGL(__FILE__, __LINE__); } void iterate() { CheckOpenGL(__FILE__, __LINE__); if(glfwWindowShouldClose(window)) { event_queue.push_back({QUIT, 0}); } CheckOpenGL(__FILE__, __LINE__); redraw(window); CheckOpenGL(__FILE__, __LINE__); glfwSwapBuffers(window); CheckOpenGL(__FILE__, __LINE__); glfwPollEvents(); } void shutdown() { glfwTerminate(); } void set_switches(DisplayMode mode_, bool mixed, int page) { display_mode = mode_; mixed_mode = mixed; display_page = page; } static const int text_page1_base = 0x400; static const int text_page2_base = 0x800; static const int text_page_size = 0x400; static const int hires_page1_base = 0x2000; static const int hires_page2_base = 0x4000; static const int hires_page_size = 8192; extern int text_row_base_offsets[24]; extern int hires_memory_to_scanout_address[8192]; bool write(int addr, unsigned char data) { // We know text page 1 and 2 are contiguous if((addr >= text_page1_base) && (addr < text_page2_base + text_page_size)) { int page = (addr >= text_page2_base) ? 1 : 0; int within_page = addr - text_page1_base - page * text_page_size; for(int row = 0; row < 24; row++) { int row_offset = text_row_base_offsets[row]; if((within_page >= row_offset) && (within_page < row_offset + 40)){ int col = within_page - row_offset; glBindTexture(GL_TEXTURE_RECTANGLE, textport_texture[page]); glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, col, row, 1, 1, GL_RED_INTEGER_EXT, GL_UNSIGNED_BYTE, &data); textport[page][row][col] = data; CheckOpenGL(__FILE__, __LINE__); } } return true; } else if(((addr >= hires_page1_base) && (addr < hires_page1_base + hires_page_size)) || ((addr >= hires_page2_base) && (addr < hires_page2_base + hires_page_size))) { int page = (addr < hires_page2_base) ? 0 : 1; int page_base = (page == 0) ? hires_page1_base : hires_page2_base; int within_page = addr - page_base; int scanout_address = hires_memory_to_scanout_address[within_page]; int row = scanout_address / 40; int col = scanout_address % 40; glBindTexture(GL_TEXTURE_RECTANGLE, hires_texture[page]); unsigned char pixels[8]; for(int i = 0; i < 8 ; i++) pixels[i] = ((data & (1 << i)) ? 255 : 0); glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, col * 8, row, 8, 1, GL_RED_INTEGER_EXT, GL_UNSIGNED_BYTE, pixels); CheckOpenGL(__FILE__, __LINE__); return true; } return false; } int text_row_base_offsets[24] = { 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x028, 0x0A8, 0x128, 0x1A8, 0x228, 0x2A8, 0x328, 0x3A8, 0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0, }; int hires_row_base_offsets[192] = { 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x0080, 0x0480, 0x0880, 0x0C80, 0x1080, 0x1480, 0x1880, 0x1C80, 0x0100, 0x0500, 0x0900, 0x0D00, 0x1100, 0x1500, 0x1900, 0x1D00, 0x0180, 0x0580, 0x0980, 0x0D80, 0x1180, 0x1580, 0x1980, 0x1D80, 0x0200, 0x0600, 0x0A00, 0x0E00, 0x1200, 0x1600, 0x1A00, 0x1E00, 0x0280, 0x0680, 0x0A80, 0x0E80, 0x1280, 0x1680, 0x1A80, 0x1E80, 0x0300, 0x0700, 0x0B00, 0x0F00, 0x1300, 0x1700, 0x1B00, 0x1F00, 0x0380, 0x0780, 0x0B80, 0x0F80, 0x1380, 0x1780, 0x1B80, 0x1F80, 0x0028, 0x0428, 0x0828, 0x0C28, 0x1028, 0x1428, 0x1828, 0x1C28, 0x00A8, 0x04A8, 0x08A8, 0x0CA8, 0x10A8, 0x14A8, 0x18A8, 0x1CA8, 0x0128, 0x0528, 0x0928, 0x0D28, 0x1128, 0x1528, 0x1928, 0x1D28, 0x01A8, 0x05A8, 0x09A8, 0x0DA8, 0x11A8, 0x15A8, 0x19A8, 0x1DA8, 0x0228, 0x0628, 0x0A28, 0x0E28, 0x1228, 0x1628, 0x1A28, 0x1E28, 0x02A8, 0x06A8, 0x0AA8, 0x0EA8, 0x12A8, 0x16A8, 0x1AA8, 0x1EA8, 0x0328, 0x0728, 0x0B28, 0x0F28, 0x1328, 0x1728, 0x1B28, 0x1F28, 0x03A8, 0x07A8, 0x0BA8, 0x0FA8, 0x13A8, 0x17A8, 0x1BA8, 0x1FA8, 0x0050, 0x0450, 0x0850, 0x0C50, 0x1050, 0x1450, 0x1850, 0x1C50, 0x00D0, 0x04D0, 0x08D0, 0x0CD0, 0x10D0, 0x14D0, 0x18D0, 0x1CD0, 0x0150, 0x0550, 0x0950, 0x0D50, 0x1150, 0x1550, 0x1950, 0x1D50, 0x01D0, 0x05D0, 0x09D0, 0x0DD0, 0x11D0, 0x15D0, 0x19D0, 0x1DD0, 0x0250, 0x0650, 0x0A50, 0x0E50, 0x1250, 0x1650, 0x1A50, 0x1E50, 0x02D0, 0x06D0, 0x0AD0, 0x0ED0, 0x12D0, 0x16D0, 0x1AD0, 0x1ED0, 0x0350, 0x0750, 0x0B50, 0x0F50, 0x1350, 0x1750, 0x1B50, 0x1F50, 0x03D0, 0x07D0, 0x0BD0, 0x0FD0, 0x13D0, 0x17D0, 0x1BD0, 0x1FD0, }; int hires_memory_to_scanout_address[8192]; static void initialize_memory_to_scanout() __attribute__((constructor)); void initialize_memory_to_scanout() { for(int row = 0; row < 192; row++) { int row_address = hires_row_base_offsets[row]; for(int byte = 0; byte < 40; byte++) { hires_memory_to_scanout_address[row_address + byte] = row * 40 + byte; } } } int font_offset = 32; unsigned char font_bytes[96 * 7 * 8] = { // 32 : 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 33 : ! 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 34 : " 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 35 : # 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 36 : $ 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 37 : % 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 38 : & 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 39 : ' 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 40 : ( 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 41 : ) 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 42 : * 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 43 : + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 44 : , 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 45 : - 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 46 : . 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 47 : / 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 48 : 0 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 49 : 1 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 50 : 2 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 51 : 3 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 52 : 4 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 53 : 5 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 54 : 6 0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 55 : 7 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 56 : 8 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 57 : 9 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 58 : : 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 59 : ; 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 60 : < 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 61 : = 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 62 : > 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 63 : ? 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 64 : @ 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 65 : A 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 66 : B 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 67 : C 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 68 : D 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 69 : E 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 70 : F 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 71 : G 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 72 : H 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 73 : I 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 74 : J 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 75 : K 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 76 : L 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 77 : M 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 78 : N 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 79 : O 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 80 : P 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 81 : Q 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 82 : R 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 83 : S 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 84 : T 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 85 : U 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 86 : V 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 87 : W 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 88 : X 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 89 : Y 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 90 : Z 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 91 : [ 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 92 : backslash 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 93 : ] 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 94 : ^ 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 95 : _ 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 96 : ` 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 97 : a 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 98 : b 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 99 : c 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 100 : d 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 101 : e 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 102 : f 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 103 : g 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, // 104 : h 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 105 : i 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 106 : j 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, // 107 : k 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 108 : l 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 109 : m 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 110 : n 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 111 : o 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 112 : p 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, // 113 : q 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, // 114 : r 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 115 : s 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 116 : t 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 117 : u 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 118 : v 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 119 : w 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 120 : x 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 121 : y 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0xFF,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00, // 122 : z 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 123 : { 0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0xFF,0xFF,0x00,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 124 : | 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00, // 125 : } 0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0xFF,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00, 0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 126 : ~ 0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, 0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 127 :  0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0x00,0xFF,0x00,0xFF,0x00,0x00, 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; };