diff --git a/ncc/examples/basic.c b/ncc/examples/basic.c deleted file mode 100644 index 1a23b0c..0000000 --- a/ncc/examples/basic.c +++ /dev/null @@ -1,2165 +0,0 @@ -// -// UVM Basic -// by Abdul Bahajaj -// -// Note to reader: When I authored this VM there were a lot of missing features from the NCC compiler ( e.g. there are no structs, unions, etc...). -// Keeping this in mind might help you understand why the code is structured in the way it is. - - -#include -#include -#include -#include -#include -#include -#include -#include - -// VM status -#define VM_STATUS_RUNNING 0 -#define VM_STATUS_DONE 1 -#define VM_STATUS_HALT 2 -#define FONT_MONOGRAM_NUMBER_OF_CHARACTERS 390 -#define FONT_MONOGRAM_HEIGHT 12 -#define FONT_MONOGRAM_WIDTH 7 - -#define FRAME_WIDTH 1200 -#define FRAME_HEIGHT 700 -#define NUM_COLS 25 -#define NUM_ROWS 21 - -/* #define DEBUG */ -#ifdef DEBUG -#define DEBUGS(s) puts(__FILE__ " : "); print_i64(__LINE__); puts(" "); puts(s); -#define DEBUGI(i) print_i64(i); -#else -#define DEBUGS(s) -#define DEBUGI(i) -#endif -#define DEBUG(s) DEBUGS(s "\n"); - -#define TRY(exp) if(exp) return 1; -#define NULLGAURD(ptr) if(ptr == NULL) return NULL; - -size_t console_width; -size_t margin = 5; -size_t char_width = 18; -size_t char_height = 32; -u32 frame_buffer[FRAME_HEIGHT][FRAME_WIDTH]; -char text[NUM_ROWS][NUM_COLS]; - -// Position of the cursor -#define MIN_COL_FIRST_LINE 2 -size_t line_idx = 0; -size_t min_line_idx = 4; -size_t col_idx = 0; -size_t min_col_idx; - -size_t row_len(size_t row_idx) -{ - for (int i = 0; i < NUM_COLS; ++i) - { - if (text[row_idx][i] == 0) - { - return i; - } - } - return NUM_COLS; -} - -u32* get_point_ptr(u32* dst, size_t frame_width, size_t x, size_t y) -{ - return dst + frame_width* y + x; -} - -int white = 0xFFFFFF; -int blue = 0x0247fe; -int red = 0xFF0000; -int green = 0x008000; -int black = 0x0; - -void textinput(u64 window_id, char ch) -{ - if(vm_status != VM_STATUS_DONE) return; - console_putchar(ch); - vm_command_text_buffer[vm_command_text_buffer_cursor] = ch; - DEBUGS(vm_command_text_buffer); - DEBUGS("\n"); - ++vm_command_text_buffer_cursor; - console_redraw_commit(); -} - -void keydown(u64 window_id, u16 keycode) -{ - if(vm_status != VM_STATUS_DONE) - { - if(keycode == KEY_ESCAPE) vm_status = VM_STATUS_HALT; - return; - } - if (keycode == KEY_ESCAPE) exit(0); - else if (keycode == KEY_BACKSPACE) - { - if (col_idx > min_col_idx) - { - col_idx = col_idx - 1; - vm_command_text_buffer_backspace(); - } - else if (line_idx > min_line_idx) - { - console_redraw_line(line_idx); - line_idx = line_idx - 1; - if(line_idx == min_line_idx) min_col_idx = MIN_COL_FIRST_LINE; - col_idx = row_len(line_idx); - } - text[line_idx][col_idx] = 0; - } - else if (keycode == KEY_RETURN) - { - vm_load_cmd(); - vm_exec(); - } - console_redraw_commit(); -} - -void anim_callback() -{ - console_redraw_commit(); - /* benchmark(); */ - - time_delay_cb(400, anim_callback); -} - -void console_print_ready() -{ - console_newline(); - console_puts("READY."); - console_newline(); - console_puts("> "); - min_col_idx = MIN_COL_FIRST_LINE; -} - -void main() -{ - DEBUGS("DEBUGGING\n"); - console_width = FRAME_WIDTH/3+75; - vm_init(); - vm_command_text_buffer_clear(); - window_create(FRAME_WIDTH, FRAME_HEIGHT, "UVM Basic", 0); - - canvas_fill(white); - console_redraw_all_text(); - - console_puts(" **** UVM Basic ****"); - console_newline(); - console_puts("Type HELP for available "); - console_newline(); - console_puts("commands"); - console_print_ready(); - - console_redraw_commit(); - - window_on_keydown(0, keydown); - window_on_textinput(0, textinput); - - time_delay_cb(0, anim_callback); - - enable_event_loop(); -} - -//=========================================================================== -/* CONSOLE */ - -// This is 12 bytes of data per char, as in 12 rows, and each byte -// represents the pixels in that row. -u8 font_monogram_data[FONT_MONOGRAM_NUMBER_OF_CHARACTERS][FONT_MONOGRAM_HEIGHT] = { - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e, 0x00, 0x00, }, // '0' - { 0x00, 0x00, 0x00, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // '1' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f, 0x00, 0x00, }, // '2' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // '3' - { 0x00, 0x00, 0x00, 0x12, 0x12, 0x11, 0x1f, 0x10, 0x10, 0x10, 0x00, 0x00, }, // '4' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // '5' - { 0x00, 0x00, 0x00, 0x0e, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // '6' - { 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00, 0x00, }, // '7' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // '8' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // '9' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, }, // '!' - { 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '"' - { 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1f, 0x0a, 0x0a, 0x1f, 0x0a, 0x00, 0x00, }, // '#' - { 0x00, 0x00, 0x00, 0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04, 0x00, 0x00, }, // '$' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x08, 0x04, 0x02, 0x11, 0x11, 0x00, 0x00, }, // '%' - { 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x1e, 0x09, 0x09, 0x16, 0x00, 0x00, }, // '&' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // "'" - { 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, }, // '(' - { 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, }, // ')' - { 0x00, 0x00, 0x00, 0x00, 0x04, 0x15, 0x0e, 0x15, 0x04, 0x00, 0x00, 0x00, }, // '*' - { 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, 0x00, 0x00, }, // '+' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x02, 0x00, }, // ',' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '-' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, }, // '.' - { 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, }, // '/' - { 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, }, // ':' - { 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04, 0x02, 0x00, }, // ';' - { 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x01, 0x06, 0x18, 0x00, 0x00, 0x00, }, // '<' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, }, // '=' - { 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00, }, // '>' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04, 0x00, 0x00, }, // '?' - { 0x00, 0x00, 0x00, 0x0e, 0x19, 0x15, 0x15, 0x19, 0x01, 0x0e, 0x00, 0x00, }, // '@' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00, 0x00, }, // 'A' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'B' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'C' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'D' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'E' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'F' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'G' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'H' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'I' - { 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'J' - { 0x00, 0x00, 0x00, 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, 0x00, 0x00, }, // 'K' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'L' - { 0x00, 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'M' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00, }, // 'N' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'O' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'P' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x18, 0x00, }, // 'Q' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'R' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'S' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'T' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'U' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04, 0x00, 0x00, }, // 'V' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x15, 0x1b, 0x11, 0x00, 0x00, }, // 'W' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, 0x00, 0x00, }, // 'X' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Y' - { 0x00, 0x00, 0x00, 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0x00, 0x00, }, // 'Z' - { 0x00, 0x00, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x00, 0x00, }, // '[' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00, }, // '\\' - { 0x00, 0x00, 0x00, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x00, 0x00, }, // ']' - { 0x00, 0x00, 0x00, 0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '^' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, }, // '_' - { 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '`' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'a' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'b' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'c' - { 0x00, 0x00, 0x00, 0x10, 0x10, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'd' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'e' - { 0x00, 0x00, 0x00, 0x0c, 0x12, 0x02, 0x0f, 0x02, 0x02, 0x02, 0x00, 0x00, }, // 'f' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'g' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'h' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'i' - { 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x11, 0x0e, }, // 'j' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x11, 0x09, 0x07, 0x09, 0x11, 0x00, 0x00, }, // 'k' - { 0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 'l' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, }, // 'm' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'n' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'o' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01, }, // 'p' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, }, // 'q' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'r' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f, 0x00, 0x00, }, // 's' - { 0x00, 0x00, 0x00, 0x02, 0x02, 0x0f, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 't' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'u' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, 0x00, 0x00, }, // 'v' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, 0x00, 0x00, }, // 'w' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x00, 0x00, }, // 'x' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'y' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, 0x00, 0x00, }, // 'z' - { 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08, 0x00, 0x00, }, // '{' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // '|' - { 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x08, 0x04, 0x04, 0x02, 0x00, 0x00, }, // '}' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '~' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // '¡' - { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x15, 0x05, 0x15, 0x0e, 0x04, 0x00, 0x00, }, // '¢' - { 0x00, 0x00, 0x00, 0x0c, 0x12, 0x02, 0x0f, 0x02, 0x02, 0x1f, 0x00, 0x00, }, // '£' - { 0x00, 0x00, 0x00, 0x00, 0x11, 0x0e, 0x0a, 0x0e, 0x11, 0x00, 0x00, 0x00, }, // '¤' - { 0x00, 0x00, 0x00, 0x11, 0x0a, 0x04, 0x1f, 0x04, 0x1f, 0x04, 0x00, 0x00, }, // '¥' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, }, // '¦' - { 0x00, 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x11, 0x0e, 0x10, 0x0f, 0x00, 0x00, }, // '§' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '¨' - { 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x15, 0x1d, 0x15, 0x1b, 0x0e, 0x00, 0x00, }, // '©' - { 0x00, 0x00, 0x00, 0x0e, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x00, }, // 'ª' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x12, 0x00, 0x00, 0x00, 0x00, }, // '«' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, }, // '¬' - { 0x00, 0x00, 0x00, 0x0e, 0x19, 0x15, 0x15, 0x19, 0x15, 0x0e, 0x00, 0x00, }, // '®' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '¯' - { 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '°' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, 0x1f, 0x00, 0x00, }, // '±' - { 0x00, 0x00, 0x00, 0x03, 0x04, 0x02, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, }, // '²' - { 0x00, 0x00, 0x00, 0x03, 0x04, 0x02, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, }, // '³' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '´' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01, }, // 'µ' - { 0x00, 0x00, 0x00, 0x1e, 0x17, 0x17, 0x17, 0x16, 0x14, 0x14, 0x00, 0x00, }, // '¶' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '·' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, }, // '¸' - { 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, }, // '¹' - { 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, }, // 'º' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00, }, // '»' - { 0x00, 0x00, 0x00, 0x01, 0x09, 0x05, 0x02, 0x15, 0x1c, 0x10, 0x00, 0x00, }, // '¼' - { 0x00, 0x00, 0x00, 0x01, 0x09, 0x05, 0x0e, 0x11, 0x08, 0x1c, 0x00, 0x00, }, // '½' - { 0x00, 0x00, 0x00, 0x07, 0x16, 0x0f, 0x04, 0x16, 0x1d, 0x10, 0x00, 0x00, }, // '¾' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x02, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // '¿' - { 0x02, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'À' - { 0x08, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Á' - { 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Â' - { 0x16, 0x09, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ã' - { 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ä' - { 0x04, 0x0a, 0x04, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Å' - { 0x00, 0x00, 0x00, 0x1e, 0x05, 0x05, 0x1f, 0x05, 0x05, 0x1d, 0x00, 0x00, }, // 'Æ' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x08, 0x06, }, // 'Ç' - { 0x02, 0x04, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'È' - { 0x08, 0x04, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'É' - { 0x04, 0x0a, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ê' - { 0x00, 0x0a, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ë' - { 0x02, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Ì' - { 0x08, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Í' - { 0x04, 0x0a, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Î' - { 0x00, 0x0a, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Ï' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x13, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'Ð' - { 0x16, 0x09, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00, }, // 'Ñ' - { 0x02, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ò' - { 0x08, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ó' - { 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ô' - { 0x16, 0x09, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Õ' - { 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ö' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0x0a, 0x00, 0x00, 0x00, }, // '×' - { 0x00, 0x00, 0x00, 0x16, 0x09, 0x19, 0x15, 0x13, 0x12, 0x0d, 0x00, 0x00, }, // 'Ø' - { 0x02, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ù' - { 0x08, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ú' - { 0x04, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Û' - { 0x00, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ü' - { 0x08, 0x04, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Ý' - { 0x00, 0x00, 0x00, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x00, 0x00, }, // 'Þ' - { 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x0d, 0x11, 0x11, 0x0d, 0x00, 0x00, }, // 'ß' - { 0x00, 0x00, 0x02, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'à' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'á' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'â' - { 0x00, 0x00, 0x16, 0x09, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ã' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ä' - { 0x00, 0x04, 0x0a, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'å' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, 0x1d, 0x05, 0x1e, 0x00, 0x00, }, // 'æ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x08, 0x06, }, // 'ç' - { 0x00, 0x00, 0x02, 0x04, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'è' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'é' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ê' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ë' - { 0x00, 0x00, 0x02, 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ì' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'í' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'î' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ï' - { 0x00, 0x00, 0x0e, 0x30, 0x18, 0x1e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ð' - { 0x00, 0x00, 0x16, 0x09, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ñ' - { 0x00, 0x00, 0x02, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ò' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ó' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ô' - { 0x00, 0x00, 0x16, 0x09, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'õ' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ö' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00, 0x00, }, // '÷' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x09, 0x15, 0x12, 0x0d, 0x00, 0x00, }, // 'ø' - { 0x00, 0x00, 0x02, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ù' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ú' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'û' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ü' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ý' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01, }, // 'þ' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ÿ' - { 0x00, 0x0e, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ā' - { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ā' - { 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ă' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ă' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x08, 0x10, }, // 'Ą' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x04, 0x18, }, // 'ą' - { 0x08, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'Ć' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'ć' - { 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'Ĉ' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'ĉ' - { 0x00, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'Ċ' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'ċ' - { 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'Č' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'č' - { 0x0a, 0x04, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'Ď' - { 0x00, 0x00, 0x50, 0x50, 0x10, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ď' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x13, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'Đ' - { 0x00, 0x00, 0x10, 0x3c, 0x10, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'đ' - { 0x00, 0x0e, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ē' - { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ē' - { 0x0a, 0x04, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ĕ' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ĕ' - { 0x00, 0x04, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ė' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ė' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x01, 0x01, 0x1f, 0x04, 0x18, }, // 'Ę' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x1e, 0x04, 0x18, }, // 'ę' - { 0x00, 0x0e, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ě' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ě' - { 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ĝ' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ĝ' - { 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ğ' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ğ' - { 0x00, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ġ' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ġ' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x0e, 0x08, 0x06, }, // 'Ģ' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ģ' - { 0x04, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ĥ' - { 0x00, 0x00, 0x08, 0x15, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ĥ' - { 0x00, 0x00, 0x00, 0x11, 0x3f, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ħ' - { 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ħ' - { 0x16, 0x09, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Ĩ' - { 0x00, 0x00, 0x16, 0x09, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ĩ' - { 0x00, 0x0e, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Ī' - { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ī' - { 0x0a, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'Ĭ' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ĭ' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x18, }, // 'Į' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x18, }, // 'į' - { 0x16, 0x09, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'İ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ı' - { 0x00, 0x00, 0x00, 0x17, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0f, 0x00, 0x00, }, // 'IJ' - { 0x00, 0x00, 0x00, 0x12, 0x00, 0x1b, 0x12, 0x12, 0x12, 0x1f, 0x10, 0x0e, }, // 'ij' - { 0x04, 0x0a, 0x00, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ĵ' - { 0x00, 0x00, 0x10, 0x28, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x11, 0x0e, }, // 'ĵ' - { 0x00, 0x00, 0x00, 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, 0x04, 0x04, }, // 'Ķ' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x11, 0x09, 0x07, 0x09, 0x11, 0x04, 0x04, }, // 'ķ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x09, 0x07, 0x09, 0x11, 0x00, 0x00, }, // 'ĸ' - { 0x08, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ĺ' - { 0x08, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, }, // 'ĺ' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x08, 0x06, }, // 'Ļ' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x08, 0x06, }, // 'ļ' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x09, 0x01, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ľ' - { 0x00, 0x00, 0x00, 0x13, 0x12, 0x0a, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 'ľ' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ŀ' - { 0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x0a, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 'ŀ' - { 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ł' - { 0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x06, 0x03, 0x02, 0x1c, 0x00, 0x00, }, // 'ł' - { 0x08, 0x04, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00, }, // 'Ń' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ń' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x04, 0x03, }, // 'Ņ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x04, 0x03, }, // 'ņ' - { 0x0a, 0x04, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00, }, // 'Ň' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ň' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'ʼn' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x10, 0x0c, }, // 'Ŋ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0c, }, // 'ŋ' - { 0x00, 0x0e, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ō' - { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ō' - { 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ŏ' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ŏ' - { 0x14, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ő' - { 0x00, 0x00, 0x14, 0x0a, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'ő' - { 0x00, 0x00, 0x00, 0x1e, 0x05, 0x05, 0x1d, 0x05, 0x05, 0x1e, 0x00, 0x00, }, // 'Œ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x15, 0x1d, 0x05, 0x0e, 0x00, 0x00, }, // 'œ' - { 0x08, 0x04, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ŕ' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'ŕ' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x11, 0x04, 0x03, }, // 'Ŗ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, 0x04, 0x03, }, // 'ŗ' - { 0x0a, 0x04, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Ř' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'ř' - { 0x08, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'Ś' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f, 0x00, 0x00, }, // 'ś' - { 0x04, 0x0a, 0x00, 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'Ŝ' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f, 0x00, 0x00, }, // 'ŝ' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e, 0x04, 0x03, }, // 'Ş' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f, 0x04, 0x03, }, // 'ş' - { 0x0a, 0x04, 0x00, 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'Š' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f, 0x00, 0x00, }, // 'š' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, }, // 'Ţ' - { 0x00, 0x00, 0x00, 0x02, 0x02, 0x0f, 0x02, 0x02, 0x02, 0x1c, 0x08, 0x06, }, // 'ţ' - { 0x0a, 0x04, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Ť' - { 0x00, 0x00, 0x08, 0x0a, 0x02, 0x0f, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 'ť' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Ŧ' - { 0x00, 0x00, 0x00, 0x02, 0x0f, 0x02, 0x0f, 0x02, 0x02, 0x1c, 0x00, 0x00, }, // 'ŧ' - { 0x16, 0x09, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ũ' - { 0x00, 0x00, 0x16, 0x09, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ũ' - { 0x00, 0x0e, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ū' - { 0x00, 0x00, 0x00, 0x0e, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ū' - { 0x0a, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ŭ' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ŭ' - { 0x0a, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ů' - { 0x00, 0x04, 0x0a, 0x04, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ů' - { 0x14, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'Ű' - { 0x00, 0x00, 0x14, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x00, 0x00, }, // 'ű' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x04, 0x18, }, // 'Ų' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x04, 0x18, }, // 'ų' - { 0x04, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x15, 0x1b, 0x11, 0x00, 0x00, }, // 'Ŵ' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, 0x00, 0x00, }, // 'ŵ' - { 0x04, 0x0a, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Ŷ' - { 0x00, 0x00, 0x04, 0x0a, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'ŷ' - { 0x00, 0x0a, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Ÿ' - { 0x08, 0x04, 0x00, 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0x00, 0x00, }, // 'Ź' - { 0x00, 0x00, 0x08, 0x04, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, 0x00, 0x00, }, // 'ź' - { 0x00, 0x04, 0x00, 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0x00, 0x00, }, // 'Ż' - { 0x00, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, 0x00, 0x00, }, // 'ż' - { 0x0a, 0x04, 0x00, 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0x00, 0x00, }, // 'Ž' - { 0x00, 0x00, 0x0a, 0x04, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, 0x00, 0x00, }, // 'ž' - { 0x00, 0x0a, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Ё' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00, 0x00, }, // 'А' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'Б' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'В' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'Г' - { 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x1f, 0x11, 0x00, }, // 'Д' - { 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, 0x00, 0x00, }, // 'Е' - { 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x15, 0x00, 0x00, }, // 'Ж' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x10, 0x0e, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'З' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x00, 0x00, }, // 'И' - { 0x00, 0x0a, 0x04, 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x00, 0x00, }, // 'Й' - { 0x00, 0x00, 0x00, 0x19, 0x05, 0x05, 0x03, 0x05, 0x09, 0x11, 0x00, 0x00, }, // 'К' - { 0x00, 0x00, 0x00, 0x1e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x00, 0x00, }, // 'Л' - { 0x00, 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'М' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'Н' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'О' - { 0x00, 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'П' - { 0x00, 0x00, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'Р' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'С' - { 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'Т' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, 0x00, 0x00, }, // 'У' - { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04, 0x00, 0x00, }, // 'Ф' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, 0x00, 0x00, }, // 'Х' - { 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x1f, 0x10, 0x00, }, // 'Ц' - { 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10, 0x00, 0x00, }, // 'Ч' - { 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x00, 0x00, }, // 'Ш' - { 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x10, 0x00, }, // 'Щ' - { 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x0e, 0x12, 0x12, 0x0e, 0x00, 0x00, }, // 'Ъ' - { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x15, 0x13, 0x00, 0x00, }, // 'Ы' - { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0f, 0x00, 0x00, }, // 'Ь' - { 0x00, 0x00, 0x00, 0x0e, 0x11, 0x10, 0x1c, 0x10, 0x11, 0x0e, 0x00, 0x00, }, // 'Э' - { 0x00, 0x00, 0x00, 0x09, 0x15, 0x15, 0x17, 0x15, 0x15, 0x09, 0x00, 0x00, }, // 'Ю' - { 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x1e, 0x11, 0x11, 0x00, 0x00, }, // 'Я' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x11, 0x1e, 0x00, 0x00, }, // 'а' - { 0x00, 0x00, 0x00, 0x1e, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'б' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x11, 0x0f, 0x11, 0x0f, 0x00, 0x00, }, // 'в' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, }, // 'г' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x0a, 0x0a, 0x1f, 0x11, 0x00, }, // 'д' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'е' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x0e, 0x04, 0x0e, 0x15, 0x00, 0x00, }, // 'ж' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x04, 0x09, 0x06, 0x00, 0x00, }, // 'з' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x19, 0x15, 0x13, 0x11, 0x00, 0x00, }, // 'и' - { 0x00, 0x00, 0x00, 0x0a, 0x04, 0x11, 0x19, 0x15, 0x13, 0x11, 0x00, 0x00, }, // 'й' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x09, 0x07, 0x09, 0x11, 0x00, 0x00, }, // 'к' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x12, 0x12, 0x12, 0x11, 0x00, 0x00, }, // 'л' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11, 0x00, 0x00, }, // 'м' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00, 0x00, }, // 'н' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00, 0x00, }, // 'о' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, }, // 'п' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x13, 0x11, 0x11, 0x0f, 0x01, 0x01, }, // 'р' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x01, 0x11, 0x0e, 0x00, 0x00, }, // 'с' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, }, // 'т' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e, }, // 'у' - { 0x00, 0x00, 0x00, 0x04, 0x04, 0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04, 0x04, }, // 'ф' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x00, 0x00, }, // 'х' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x1f, 0x10, 0x00, }, // 'ц' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x00, 0x00, }, // 'ч' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x00, 0x00, }, // 'ш' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x10, 0x00, }, // 'щ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x0e, 0x12, 0x0e, 0x00, 0x00, }, // 'ъ' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x13, 0x00, 0x00, }, // 'ы' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0f, 0x11, 0x0f, 0x00, 0x00, }, // 'ь' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x1c, 0x11, 0x0e, 0x00, 0x00, }, // 'э' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x15, 0x17, 0x15, 0x09, 0x00, 0x00, }, // 'ю' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x11, 0x11, 0x1e, 0x11, 0x00, 0x00, }, // 'я' - { 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, 0x00, 0x00, }, // 'ё' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '—' - { 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // '’' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, }, // '…' - { 0x00, 0x00, 0x00, 0x0c, 0x12, 0x07, 0x02, 0x07, 0x12, 0x0c, 0x00, 0x00, }, // '€' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x1e, 0x1f, 0x1e, 0x04, 0x00, 0x00, }, // '←' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x1f, 0x0e, 0x0e, 0x00, 0x00, }, // '↑' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0f, 0x1f, 0x0f, 0x04, 0x00, 0x00, }, // '→' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x00, }, // '↓' - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, // ' ' -}; - -u32 monogram_ascii_to_idx[127] = { - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 0xFFFF, - 389, // 0x20 ' ' - 10, // 0x21 '!' - 11, // 0x22 '"' - 12, // 0x23 '#' - 13, // 0x24 '$' - 14, // 0x25 '%' - 15, // 0x26 '&' - 16, // 0x27 ''' - 17, // 0x28 '(' - 18, // 0x29 ')' - 19, // 0x2a '*' - 20, // 0x2b '+' - 21, // 0x2c ',' - 22, // 0x2d '-' - 23, // 0x2e '.' - 24, // 0x2f '/' - 0, // 0x30 '0' - 1, // 0x31 '1' - 2, // 0x32 '2' - 3, // 0x33 '3' - 4, // 0x34 '4' - 5, // 0x35 '5' - 6, // 0x36 '6' - 7, // 0x37 '7' - 8, // 0x38 '8' - 9, // 0x39 '9' - 25, // 0x3a ':' - 26, // 0x3b ';' - 27, // 0x3c '<' - 28, // 0x3d '=' - 29, // 0x3e '>' - 30, // 0x3f '?' - 31, // 0x40 '@' - 32, // 0x41 'A' - 33, // 0x42 'B' - 34, // 0x43 'C' - 35, // 0x44 'D' - 36, // 0x45 'E' - 37, // 0x46 'F' - 38, // 0x47 'G' - 39, // 0x48 'H' - 40, // 0x49 'I' - 41, // 0x4a 'J' - 42, // 0x4b 'K' - 43, // 0x4c 'L' - 44, // 0x4d 'M' - 45, // 0x4e 'N' - 46, // 0x4f 'O' - 47, // 0x50 'P' - 48, // 0x51 'Q' - 49, // 0x52 'R' - 50, // 0x53 'S' - 51, // 0x54 'T' - 52, // 0x55 'U' - 53, // 0x56 'V' - 54, // 0x57 'W' - 55, // 0x58 'X' - 56, // 0x59 'Y' - 57, // 0x5a 'Z' - 58, // 0x5b '[' - 59, // 0x5c '\' - 60, // 0x5d ']' - 61, // 0x5e '^' - 62, // 0x5f '_' - 63, // 0x60 '`' - 64, // 0x61 'a' - 65, // 0x62 'b' - 66, // 0x63 'c' - 67, // 0x64 'd' - 68, // 0x65 'e' - 69, // 0x66 'f' - 70, // 0x67 'g' - 71, // 0x68 'h' - 72, // 0x69 'i' - 73, // 0x6a 'j' - 74, // 0x6b 'k' - 75, // 0x6c 'l' - 76, // 0x6d 'm' - 77, // 0x6e 'n' - 78, // 0x6f 'o' - 79, // 0x70 'p' - 80, // 0x71 'q' - 81, // 0x72 'r' - 82, // 0x73 's' - 83, // 0x74 't' - 84, // 0x75 'u' - 85, // 0x76 'v' - 86, // 0x77 'w' - 87, // 0x78 'x' - 88, // 0x79 'y' - 89, // 0x7a 'z' - 90, // 0x7b '{' - 91, // 0x7c '|' - 92, // 0x7d '}' - 93, // 0x7e '~' -}; - -void console_redraw_commit() -{ - console_redraw_line(line_idx); - - for (u32 row = 0; row < NUM_ROWS; ++row) - { - for (int col = 0; col < NUM_COLS; ++col) - { - char ch = text[row][col]; - - if (ch == 0) continue; - - console_draw_char(ch, col, row); - } - } - - u64 t = time_current_ms(); - bool cursor_on = (t / 400) % 2; - - if (cursor_on) - { - console_draw_char('_', col_idx, line_idx); - } - - window_draw_frame(0, frame_buffer); -} - -size_t console_get_line_pos(size_t line_num) -{ - return margin + char_height*line_num; -} - -void console_redraw_line(size_t start_y) -{ - size_t start = console_get_line_pos(start_y); - size_t end = console_get_line_pos(start_y + 1) + FONT_MONOGRAM_HEIGHT; - - for(u64 y = start; y < end; ++y) - memset32(((u32*)frame_buffer) + FRAME_WIDTH * y, blue, console_width); -} - -void console_redraw_all_text() -{ - for(size_t y = 0; y < FRAME_HEIGHT; ++y) - memset32(((u32*)frame_buffer) + FRAME_WIDTH * y, blue, console_width); -} - -void console_make_space() -{ - for(size_t cur=0; cur < (NUM_ROWS-1); ++cur) - memcpy(text[cur], text[cur+1], NUM_COLS); - memset(text[NUM_ROWS-1], 0, NUM_COLS); - col_idx=0; - console_redraw_all_text(); -} - -void console_newline() -{ - if (line_idx + 1 < NUM_ROWS) - { - console_redraw_line(line_idx); - line_idx = line_idx + 1; - col_idx = 0; - } - else console_make_space(); -} - -void console_putchar(char ch) -{ - text[line_idx][col_idx] = ch; - - if (col_idx + 1 < NUM_COLS) - { - col_idx = col_idx + 1; - } - else if (line_idx + 1 < NUM_ROWS) - { - size_t old_col_idx = col_idx; - console_newline(); - min_col_idx = 0; - if(old_col_idx >= NUM_COLS) - col_idx = col_idx + 1; - } - else - { - console_make_space(); - if(min_line_idx > 0) - min_line_idx = min_line_idx - 1; - } -} - -void console_puts(u8* ch) -{ - while((*ch) != 0) - { - console_putchar(*ch); - ++ch; - } -} - -char console_input_buff[20]; - -void console_print_i64(i64 n) -{ - memset(console_input_buff, 0, sizeof(console_input_buff)); - u8 buff_start = 18; - u8 is_neg = 0; - - if(0 > n) - { - is_neg = 1; - n = -n; - } - else if (n == 0) - { - console_input_buff[buff_start] = 48; - --buff_start; - } - - for(; n!=0; --buff_start) - { - console_input_buff[buff_start] = (n % 10) + 48; - n = n / 10; - } - - if (is_neg) - { - DEBUG("setting neg sign\n"); - console_input_buff[buff_start] = '-'; - --buff_start; - } - - console_puts(console_input_buff+(buff_start+1)); -} - -void console_draw_char(char ch, size_t row_num, size_t col_num) -{ - row_num = margin + char_width * row_num; - col_num = console_get_line_pos(col_num); - u8 scale = 3; - u32 char_idx = monogram_ascii_to_idx[ch]; - - u32* d = get_point_ptr((u32*)frame_buffer, FRAME_WIDTH, row_num, col_num); - - for (u64 y = 0; y < FONT_MONOGRAM_HEIGHT; ++y) - { - u8 pixel_bits = font_monogram_data[char_idx][y]; - for (u8 i = 0; i < scale; ++i) - { - u64 x = 0; - u8 pb = pixel_bits; - - while (pb) - { - memset32(d + x, blue, scale); - if (pb & 1) memset32(d + x, 0xFFFFFF, scale); - x = x + scale; - pb = pb >> 1; - } - - d = d + FRAME_WIDTH; - } - } -} - - -//=========================================================================== -/* CANVAS */ - -size_t canvas_width; -size_t canvas_height; -#define CANVAS_PLOT_POINT_SIZE 5 - -u8 canvas_plot(u64 x, u64 y, u64 color) -{ - TRY(canvas_coord_gaurd(x, y)); - u32* p = get_point_ptr((u32*)frame_buffer, FRAME_WIDTH, x, y); - - for(u32 y = 0; y < CANVAS_PLOT_POINT_SIZE; ++y) - { - memset32(p + console_width, color, CANVAS_PLOT_POINT_SIZE); - p = p + FRAME_WIDTH; - } - return 0; -} - -u8 canvas_coord_gaurd(u32 x, u32 y) -{ - if((x + console_width) >= FRAME_WIDTH) - { - console_error("The given X coordinate exceeds the size of the canvas width"); - return 1; - } - if(y >= FRAME_HEIGHT) - { - console_error("The given y coordinate exceeds the size of the canvas height"); - return 1; - } - - return 0; -} - -void canvas_fill(u32 color) -{ - memset32(frame_buffer, color, sizeof(frame_buffer) / sizeof(u32)); -} - -//=========================================================================== -/* INTERPRETER */ - -u64 vm_status = VM_STATUS_DONE; - -char vm_command_text_buffer[1024]; -size_t vm_command_text_buffer_cursor =0; -size_t vm_command_text_buffer_read = 0; - -void vm_command_text_buffer_clear() -{ - memset(vm_command_text_buffer, 0, sizeof(vm_command_text_buffer)); - vm_command_text_buffer_read = 0; - vm_command_text_buffer_cursor = 0; -} - -void vm_command_text_buffer_backspace() -{ - if(vm_command_text_buffer_cursor > 0) - { - vm_command_text_buffer[vm_command_text_buffer_cursor] = 0; - --vm_command_text_buffer_cursor; - } -} - -#define OP_PUSH 0 -// pops the top of the stack, assigns the value to the var -#define OP_SET_VAR 1 -// pushes a var value to the stack -#define OP_GET_VAR 2 - -#define OP_JUMP 3 // jumps to instructions within a command -#define OP_JUMP_IF 4 -#define OP_JUMP_IF_NOT 5 - -// binary arth ops pop 2 vals from the stack, push the result to the stack -#define OP_ADD 6 -#define OP_SUB 7 -#define OP_MULT 8 -#define OP_DIV 9 - -#define OP_GT 10 -#define OP_LT 11 -#define OP_GT_EQ 12 -#define OP_LT_EQ 13 - -#define OP_EQ 14 -#define OP_NOT_EQ 15 - -#define OP_PRINT_INT 16 - -// Jumps to a command, as opposed to jumping to instructions as OP_JUMP does -#define OP_GOTO 17 - -// draws a pixel at x, y -#define OP_PLOT 18 -#define OP_LINE 19 -#define OP_FILL 20 -#define OP_HELP_ALL 21 - -#define OP_HALT 22 // stops execution - -#define OP_EXIT 23 // Exits the program - -#define OP_SLEEP 24 -#define OP_RAND 25 -#define OP_MOD 26 -#define OP_PRINT_STR 27 - -char* error_prefix = "Error: "; - -// Maps symbols to var positions -size_t vm_intern_capacity = 1024; -u64** vm_intern_buffer; - -// Linkedlist containing sorterd commands -// Each command is a list of instructions -// represented this way in order to insert new commands in between old ones -// the number of the command. e.g. 10 LET x 10 -> command[VM_COMMANDS_NUM] = 10 -#define VM_COMMANDS_NUM 0 -// The number of instructions that the command can hold -#define VM_COMMANDS_CAPACITY 1 -// The number of instructions that the command currently hold -#define VM_COMMANDS_CUR 2 -// command[VM_COMMANDS_NEXT] holds the address of the next command -#define VM_COMMANDS_NEXT 3 -// command[VM_COMMANDS_INSTS_BUFFER] is the buffer that actually holds the instructions -#define VM_COMMANDS_INSTS_BUFFER 4 - -u64** vm_commands_selected = NULL; -u64** vm_commands_root = NULL; - -// Vector containing variable values -size_t vm_vars_allocated = 0; -i64 vm_vars[32768]; - -// Stack that can be pushed to and poped from -size_t vm_stack_cursor = 0; -i64 vm_stack[1024]; - -u64** vm_commands_alloc(u64 num) -{ - size_t capacity = 256; - size_t meta_data_size = sizeof(u64*)*5; - size_t inst_buffer_size = sizeof(u64)*capacity; - - u64** command_meta = (u64**)malloc(meta_data_size); - NULLGAURD(command_meta); - memset(command_meta, 0, meta_data_size); - u64* inst_buffer = (u64*) malloc(inst_buffer_size); - NULLGAURD(inst_buffer); - memset(inst_buffer, 0, inst_buffer_size); - command_meta[VM_COMMANDS_CAPACITY] = (u64*)capacity; - command_meta[VM_COMMANDS_NUM] = (u64*)num; - command_meta[VM_COMMANDS_INSTS_BUFFER] = inst_buffer; - return command_meta; -} - -u64** vm_command_find(u64 num) -{ - for(u64** cur_cmd = vm_commands_root; cur_cmd != 0; cur_cmd = (u64**)cur_cmd[VM_COMMANDS_NEXT]) - { - u64 cur_cmd_num = (u64)cur_cmd[VM_COMMANDS_NUM]; - if (cur_cmd_num == num) return cur_cmd; - } - return 0; -} - -void vm_command_free(u64** cmd) -{ - free((void*)cmd[VM_COMMANDS_INSTS_BUFFER]); - free((void*) cmd); -} - -u64** vm_command_create(u64 num) -{ - - u64** new_cmd = vm_commands_alloc(num); - NULLGAURD(new_cmd); - - if(vm_commands_root == NULL) - { // initialize the root - DEBUG("Init root\n"); - new_cmd[VM_COMMANDS_NEXT] = (u64*)vm_commands_root; - vm_commands_root = new_cmd; - return new_cmd; - } - - DEBUG("Finding command\n"); - u64** prev_cmd = 0; - for(u64** cur_cmd = vm_commands_root;; cur_cmd = (u64**)cur_cmd[VM_COMMANDS_NEXT]) - { - if(cur_cmd == NULL) - { - DEBUG("Inserting command at the end"); - prev_cmd[VM_COMMANDS_NEXT] = (u64*)new_cmd; - break; - } - u64 cur_cmd_num = (u64)cur_cmd[VM_COMMANDS_NUM]; - if(cur_cmd_num > num) - { // insert command before - DEBUG("Inserting commands in between commands"); - if(cur_cmd == vm_commands_root) vm_commands_root = new_cmd; - prev_cmd[VM_COMMANDS_NEXT] = (u64*)new_cmd; - new_cmd[VM_COMMANDS_NEXT] = (u64*)cur_cmd; - break; - } - else if(cur_cmd_num == num) - { // insert command exactly at - DEBUG("Replacing existing command"); - if(cur_cmd == vm_commands_root) vm_commands_root = new_cmd; - prev_cmd[VM_COMMANDS_NEXT] = (u64*)new_cmd; - new_cmd[VM_COMMANDS_NEXT] = (u64*)cur_cmd[VM_COMMANDS_NEXT]; - vm_command_free(cur_cmd); - break; - } - prev_cmd = cur_cmd; - } - - return new_cmd; -} - -u64 vm_alloc_var() -{ - u64 allocated = vm_vars_allocated; - ++vm_vars_allocated; - return allocated; -} - -// When a symbol is interned a small area of memory that holds some meta data about the symbol is allocated -// stores the actual string that represents the symbol -#define SYM_META_STR 0 -// stores the index of the variable in vm_vars. vm_vars[sym_meta[SYM_META_LOC]] = the value of the symbol as set by LET -#define SYM_META_LOC 1 - -u64* vm_alloc_sym_meta() -{ - size_t size = sizeof(u64)*3; - u64* sym_meta = (u64*)malloc(size); - NULLGAURD(sym_meta); - memset(sym_meta, 0, size); - return sym_meta; -} - -u8 vm_intern_buffer_alloc() -{ - DEBUGS("Allocating intern buffer with size: "); - DEBUGI(vm_intern_capacity); - DEBUG(""); - - size_t interned_symbols_size = sizeof(u64**) * vm_intern_capacity; - vm_intern_buffer = (u64**)(malloc(interned_symbols_size)); - if(vm_intern_buffer == NULL) return 1; - memset(vm_intern_buffer, 0, interned_symbols_size); - return 0; -} - -void resize_interned_sym_buffer() -{ - size_t old_capacity = vm_intern_capacity; - u64** old_buffer = vm_intern_buffer; - - vm_intern_capacity = vm_intern_capacity * 2; - vm_intern_buffer_alloc(); - - DEBUG("Copying interned symbols from old to new buffer"); - for(size_t cursor = 0; cursor < old_capacity; ++cursor) - { - u64* sym_meta = old_buffer[cursor]; - char* str = sym_meta[SYM_META_STR]; - u32 str_hash = hash(str); - u64 idx = (vm_intern_capacity - 1) & str_hash; - - DEBUG("Finding a spot for symbol: "); - DEBUGS(str); - DEBUG(""); - - while(vm_intern_buffer[idx] != 0) - { - DEBUGS("Couldn't find a spot at index: "); - DEBUGI(idx); - DEBUG(""); - ++idx; - if(idx >= vm_intern_buffer) idx = 0; - } - DEBUG("Found a spot at index: "); - DEBUGI(idx); - DEBUG(""); - - vm_intern_buffer[idx] = sym_meta; - } -} - -u64* vm_intern(u8* sym, u64 len, u32 hash) -{ - u64 idx = (vm_intern_capacity - 1) & hash; - DEBUG("Interning a new sym: "); - DEBUGS(sym); - for(size_t cursor = idx;; ++cursor) - { - if (cursor >= vm_intern_capacity) - { - if(idx == 0) break; - cursor = 0; - } - - DEBUGS("Attempting to locate symbol at index: "); - DEBUGI(cursor); - DEBUG(""); - - u64* sym_meta = vm_intern_buffer[cursor]; - if (sym_meta == NULL) - { - DEBUG("Symbol not found, creating a new entry"); - char* sym_str; - sym_str = (char*)malloc(len+1); - NULLGAURD(sym_str); - memcpy(sym_str, sym, len); - sym_str[len] = 0; - - sym_meta = vm_alloc_sym_meta(); - NULLGAURD(sym_meta); - sym_meta[SYM_META_STR] = (u64)sym_str; - - vm_intern_buffer[cursor] = (u64)sym_meta; - return sym_meta; - } - else if (strncmp(sym_meta[SYM_META_STR], sym, len) == 0) - { - DEBUG("Symbol have been found"); - return sym_meta; - } - else if(cursor == (idx-1)) - { - break; - } - } - - DEBUG("Not enough space in intern buffer"); - resize_interned_sym_buffer(); - DEBUG("Done resizing intern buffer"); - return vm_intern(sym, len, hash); -} - -u8 vm_symbol_is_initialized(u64* sym) -{ - return sym[SYM_META_LOC] != 0; -} - -u64 vm_symbol_init_or_get_var(u64* sym) -{ - if(!vm_symbol_is_initialized(sym)) - { - sym[SYM_META_LOC] = ++vm_vars_allocated; - } - return sym[SYM_META_LOC]-1; -} - -void vm_symbol_init_val(u64* sym, u64 val) -{ - u64 var = vm_symbol_init_or_get_var(sym); - vm_vars[var] = val; -} - -// translates symbol strings to symbols -i64 vm_symbol_get_var(u64* sym) -{ - if(!vm_symbol_is_initialized(sym)) - { - console_newline(); - console_puts(error_prefix); - console_puts("Trying to access "); - console_newline(); - console_puts("an uninitialized variable"); - console_puts(sym[SYM_META_STR]); - return -1; - } - return sym[SYM_META_LOC]-1; -} - -u32 hash(u8 *str) -{ - u32 hash = 5381; - u8 c; - - while (c = *str) - { - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - ++str; - } - - return hash; -} - -u64* vm_commands_sym_else; -u64* vm_commands_sym_let; -u64* vm_commands_sym_goto; -u64* vm_commands_sym_run; -u64* vm_commands_sym_if; -u64* vm_commands_sym_plot; -u64* vm_commands_sym_line; -u64* vm_commands_sym_clear; -u64* vm_commands_sym_help; -u64* vm_commands_sym_halt; -u64* vm_commands_sym_exit; -u64* vm_commands_sym_quit; -u64* vm_commands_sym_fill; -u64* vm_commands_sym_sleep; -u64* vm_commands_sym_rand; -u64* vm_commands_sym_print; - -u64* vm_init_sym(char* sym) -{ - return vm_intern(sym, strlen(sym), hash(sym)); -} - -int vm_init() -{ - TRY(vm_intern_buffer_alloc()); - - vm_commands_sym_else = vm_init_sym("ELSE"); - vm_commands_sym_let = vm_init_sym("LET"); - vm_commands_sym_goto = vm_init_sym("GOTO"); - vm_commands_sym_run = vm_init_sym("RUN"); - vm_commands_sym_if = vm_init_sym("IF"); - vm_commands_sym_plot = vm_init_sym("PLOT"); - vm_commands_sym_line = vm_init_sym("LINE"); - vm_commands_sym_clear = vm_init_sym("CLEAR"); - vm_commands_sym_help = vm_init_sym("HELP"); - vm_commands_sym_halt = vm_init_sym("HALT"); - vm_commands_sym_exit = vm_init_sym("EXIT"); - vm_commands_sym_quit = vm_init_sym("QUIT"); - vm_commands_sym_fill = vm_init_sym("FILL"); - vm_commands_sym_sleep = vm_init_sym("SLEEP"); - vm_commands_sym_rand = vm_init_sym("RAND"); - vm_commands_sym_print = vm_init_sym("PRINT"); - - vm_symbol_init_val(vm_init_sym("BLUE"), blue); - vm_symbol_init_val(vm_init_sym("RED"), red); - vm_symbol_init_val(vm_init_sym("GREEN"), green); - vm_symbol_init_val(vm_init_sym("BLACK"), black); - vm_symbol_init_val(vm_init_sym("WHITE"), white); - - canvas_width = FRAME_WIDTH - console_width-CANVAS_PLOT_POINT_SIZE; - canvas_height = FRAME_HEIGHT-CANVAS_PLOT_POINT_SIZE; - vm_symbol_init_val(vm_init_sym("CWIDTH"), canvas_width); - vm_symbol_init_val(vm_init_sym("CHEIGHT"), canvas_height); - - return 0; -} - -void vm_command_double_size() -{ - u64* old_buff = vm_commands_selected[VM_COMMANDS_INSTS_BUFFER]; - size_t old_capacity = (size_t)vm_commands_selected[VM_COMMANDS_CAPACITY]; - size_t new_capacity = old_capacity*2; - size_t old_size = old_capacity*sizeof(u64); - size_t new_size = new_capacity*sizeof(u64); - - u64* new_buff = (u64*)malloc(new_size); - if(new_buff == NULL) - { - DEBUG("Failed to allocate more memory for the selected command"); - exit(1); - } - - memset(new_buff, 0, new_size); - memcpy(new_buff, old_buff, old_size); - vm_commands_selected[VM_COMMANDS_INSTS_BUFFER] = new_buff; - vm_commands_selected[VM_COMMANDS_CAPACITY] = new_capacity; - free((void*)old_buff); -} - -u64 vm_bytecode_pointer_inc() -{ - u64 current_val = (u64)vm_commands_selected[VM_COMMANDS_CUR]; - vm_commands_selected[VM_COMMANDS_CUR] = (u64*)(current_val + 1); - if(vm_commands_selected[VM_COMMANDS_CUR] >= vm_commands_selected[VM_COMMANDS_CAPACITY]) - { - DEBUG("Exceeded command capacity"); - vm_command_double_size(); - } - return current_val; -} - -u64 vm_bytecode_get(u8 op, u64 arg) -{ - return ((u64)(op & 255) << 56) | (arg & (((u64)1<<56) - 1)); -} - -void vm_bytecode_patch(u64 inst_num, u8 op, u64 arg) -{ - vm_commands_selected[VM_COMMANDS_INSTS_BUFFER][inst_num] = vm_bytecode_get(op, arg); -} - -void vm_bytecode_emit(u8 op, u64 arg) -{ - DEBUGS("VM command capacity"); - DEBUGI(vm_commands_selected[VM_COMMANDS_CAPACITY]); - DEBUG(""); - u64 pos = (u64)vm_commands_selected[VM_COMMANDS_CUR]; - vm_commands_selected[VM_COMMANDS_INSTS_BUFFER][pos] = vm_bytecode_get(op, arg); - vm_bytecode_pointer_inc(); -} - -void ignore_ws() -{ - while(vm_command_text_buffer_cursor > vm_command_text_buffer_read && - vm_command_text_buffer[vm_command_text_buffer_read] == 32) - ++vm_command_text_buffer_read; -} - -u8 peek_ch(u8 n) -{ - ignore_ws(); - if(vm_command_text_buffer_read >= vm_command_text_buffer_cursor) return 0; - return (u8)vm_command_text_buffer[vm_command_text_buffer_read + n]; -} - -u8 peek_next() -{ - return peek_ch(0); -} - -u8 read_ch() -{ - ignore_ws(); - u8 ret = (u8)vm_command_text_buffer[vm_command_text_buffer_read]; - ++vm_command_text_buffer_read; - return ret; -} - -u8 did_read_all_input() -{ - return vm_command_text_buffer_read >= vm_command_text_buffer_cursor; -} - -i64 read_uint() -{ - ignore_ws(); - size_t start = vm_command_text_buffer_read; - u64 acc = 0; - while(!did_read_all_input()) - { - - u8 cur_char = (u8)vm_command_text_buffer[vm_command_text_buffer_read]; - - cur_char = cur_char - 48; - if(cur_char > 9) - { - break; - } - - acc = acc * 10 + cur_char; - ++vm_command_text_buffer_read; - } - - if(start == vm_command_text_buffer_read) return -1; - return acc; -} - -// TODO combine read_string and read_sym to some common func -u64* read_string() -{ - ignore_ws(); - u8 bracket = vm_command_text_buffer[vm_command_text_buffer_read]; - if(bracket != '"') return NULL; - - size_t str_start = ++vm_command_text_buffer_read; - - u32 hash = 5381; - while(!did_read_all_input()) - { - u8 cur_char = (u8)vm_command_text_buffer[vm_command_text_buffer_read]; - if (cur_char == '\\') - { - ++vm_command_text_buffer_read; - } - else if (cur_char == '"') break; - hash = ((hash << 5) + hash) + cur_char; - - ++vm_command_text_buffer_read; - } - if(vm_command_text_buffer_read == str_start) return NULL; - - return vm_intern((u8*) (vm_command_text_buffer+str_start), vm_command_text_buffer_read-str_start, hash); -} - -u64* read_sym() -{ - DEBUG("Reading sym"); - ignore_ws(); - size_t sym_start = vm_command_text_buffer_read; - u32 hash = 5381; - while(!did_read_all_input()) - { - u8 cur_char = (u8)vm_command_text_buffer[vm_command_text_buffer_read]; - // TODO accept symbols with numbers, _, etc - if(!((90 >= cur_char && cur_char >= 65) || (122 >= cur_char && cur_char >= 97))) break; - hash = ((hash << 5) + hash) + cur_char; - ++vm_command_text_buffer_read; - } - if(vm_command_text_buffer_read == sym_start) return NULL; - return vm_intern((u8*) (vm_command_text_buffer+sym_start), vm_command_text_buffer_read-sym_start, hash); -} - -void console_error(char* err) -{ - console_newline(); - console_puts(error_prefix); - console_puts(err); - console_newline(); -} - -u8 vm_emit_args(u8 expected_args_count) -{ - char current = read_ch(); - if(current != '(') - { - console_error("Expected to find an ( but did not"); - return 1; - } - current = peek_next(); - u8 actual_args_count = 0; - while(current != ')') - { - if(current == 0) - { - console_error("Expected function call to end with )"); - return 1; - } - else if (actual_args_count > expected_args_count) - { - console_error("Function got too many arguments"); - return 1; - } - ++actual_args_count; - vm_emit_exp(); - } - read_ch(); - return 0; -} - -u64 vm_emit_prim() -{ - i64 num = read_uint(); - if(num >= 0) - { - vm_bytecode_emit(OP_PUSH, num); - return 0; - } - - u64* sym = read_sym(); - char next_ch = peek_next(); - - if(sym != 0) - { - if(next_ch == '(') - { - if (sym == vm_commands_sym_rand) - { - vm_emit_args(0); - vm_bytecode_emit(OP_RAND, 0); - } - else - { - console_error("Undefined function"); - return 1; - } - return 0; - } - - i64 var = vm_symbol_get_var(sym); - if(0 > var) return 1; - vm_bytecode_emit(OP_GET_VAR, var); - return 0; - } - - if(next_ch == '(') - { - read_ch(); - vm_emit_exp(); - next_ch = read_ch(); - if(next_ch != ')') - { - console_error("Expected to find ) but did not"); - return 1; - } - return 0; - } - - if (next_ch == ')') return 0; - - console_error("Unexpected token in expression"); - return 1; -} - -u64 vm_emit_factor() -{ - u8 next_ch; - u8 op; - - TRY(vm_emit_prim()); - while(1) - { - next_ch = peek_next(); - if('*' == next_ch) op = OP_MULT; - else if('/' == next_ch) op = OP_DIV; - else if('%' == next_ch) op = OP_MOD; - else break; - - read_ch(); - TRY(vm_emit_prim()); - vm_bytecode_emit(op, 0); - } - - return 0; -} - -u64 emit_term() -{ - u8 op; - u8 next_ch; - - TRY(vm_emit_factor()); - while(1) - { - next_ch = peek_next(); - if('+' == next_ch) op = OP_ADD; - else if('-' == next_ch) op = OP_SUB; - else break; - - read_ch(); - TRY(vm_emit_factor()); - vm_bytecode_emit(op, 0); - } - return 0; -} - -u64 vm_emit_comparison() -{ - u8 op; - u8 next_ch; - - TRY(emit_term()); - while(1) - { - next_ch = peek_next(); - if('>' == next_ch) - { - read_ch(); - next_ch = peek_next(); - op = OP_GT; - if ('=' == next_ch) - { - op = OP_GT_EQ; - read_ch(); - } - } - else if('<' == next_ch) - { - read_ch(); - next_ch = peek_next(); - op = OP_LT; - if ('=' == next_ch) - { - op = OP_LT_EQ; - read_ch(); - } - } - else break; - - TRY(emit_term()); - vm_bytecode_emit(op, 0); - } - return 0; -} - -u64 vm_emit_exp() -{ - u8 op; - u8 next_ch; - - TRY(vm_emit_comparison()); - - while(1) - { - next_ch = peek_next(); - - if(next_ch == '!' && peek_ch(1) == '=') op = OP_NOT_EQ; - else if(next_ch == '=' && peek_ch(1) == '=') op = OP_EQ; - else break; - read_ch(); - read_ch(); - TRY(vm_emit_comparison()); - - vm_bytecode_emit(op, 0); - } - return 0; -} - -void emit_print_str(char* s) -{ - u64* interned_s = vm_intern(s, strlen(s), hash(s)); - u64 var = vm_symbol_init_or_get_var(interned_s); - vm_vars[var] = (u64)interned_s; - vm_bytecode_emit(OP_PRINT_STR, var); -} - -u8 vm_emit_cmd(u64* command) -{ - DEBUG("Emitting command"); - - if(command == vm_commands_sym_help) - { - u64* sym = read_sym(); - if(sym == NULL) - { - DEBUG("Emitting help command"); - vm_bytecode_emit(OP_HELP_ALL, 0); - } - else if (sym == vm_commands_sym_let) - emit_print_str("Assigns the value of the expression to the variable named by the symbol. LET {symbol} {expression}"); - else if (sym == vm_commands_sym_goto) - emit_print_str("Goes to a loaded command. Commands can be loaded by prefixing them with a number. GOTO {cmd number}"); - else if (sym == vm_commands_sym_run) - emit_print_str("Runs loaded commands. Commands can be loaded by prefixing them with a number"); - else if (sym == vm_commands_sym_if) - emit_print_str("IF {predicate expression} {then command} ELSE {else command}"); - else if (sym == vm_commands_sym_plot) - emit_print_str("Plots a dot at x and y. PLOT {x} {y} {color}"); - else if (sym == vm_commands_sym_line) - emit_print_str("Draws a line from (x0, y0) to (x1, y1). LINE {x0} {y0} {x1} {y1} {color}"); - else if (sym == vm_commands_sym_clear) - emit_print_str("Clears the canvas"); - else if (sym == vm_commands_sym_halt) - emit_print_str("Stops command execution. You can use it to stop loops"); - else if (sym == vm_commands_sym_exit) - emit_print_str("Exit the program"); - else if (sym == vm_commands_sym_quit) - emit_print_str("Same as exit"); - else if (sym == vm_commands_sym_fill) - emit_print_str("Fills the canvas with a color. FILL {color}"); - else if (sym == vm_commands_sym_sleep) - emit_print_str("Sleep before executing the next command. SLEEP {time in milliseconds}"); - else if (sym == vm_commands_sym_rand) - emit_print_str("A function that returns a random number. Example: LET x RAND()"); - else if (sym == vm_commands_sym_print) - emit_print_str("Prints a string or a number. PRINT \"SOME STRING\""); - else - { - console_error("Command or function is not found"); - return 1; - } - } - - else if(command == vm_commands_sym_let) - { - DEBUG("Emitting LET command"); - u64* sym = read_sym(); - if (sym == NULL) - { - console_error("LET is expected to be followed by a symbol but was not"); - return 1; - } - TRY(vm_emit_exp()); - u64 var = vm_symbol_init_or_get_var(sym); - vm_bytecode_emit(OP_SET_VAR , var); - } - else if (command == vm_commands_sym_print) - { - DEBUG("Emitting print"); - u64* str = read_string(); - if(str != NULL) - { - DEBUG("Printing string"); - u64 var = vm_symbol_init_or_get_var(str); - vm_vars[var] = (u64)str; - vm_bytecode_emit(OP_PRINT_STR, var); - } - else - { - if(vm_emit_exp()) - { - console_error("PRINT expects to be followed by a string or an expression"); - return 1; - } - DEBUG("Printing int"); - vm_bytecode_emit(OP_PRINT_INT, 0); - } - } - else if (command == vm_commands_sym_sleep) - { - TRY(vm_emit_exp()); - vm_bytecode_emit(OP_SLEEP, 0); - } - else if (command == vm_commands_sym_goto) - { - DEBUG("Emitting GOTO"); - TRY(vm_emit_exp()); - vm_bytecode_emit(OP_GOTO, 0); - } - else if (command == vm_commands_sym_if) - { - DEBUG("Emitting IF"); - TRY(vm_emit_exp()); - u64 jump_to_else_pos = vm_bytecode_pointer_inc(); // resever inst to jump to else if pred is false - command = read_sym(); - TRY(vm_emit_cmd(command)); // Then cmd - - u64 jump_to_else_end_pos = vm_bytecode_pointer_inc(); // reserve inst to jump to end of else; - - // emitting else - u64* else_sym = read_sym(); - if(else_sym != vm_commands_sym_else) - { - console_error("Expected the Then clause to be followed by ELSE"); - return 1; - } - u64 start_of_else = (u64)vm_commands_selected[VM_COMMANDS_CUR]; - command = read_sym(); - TRY(vm_emit_cmd(command)); // Then cmd - - u64 end_of_else = (u64)vm_commands_selected[VM_COMMANDS_CUR]; - - vm_bytecode_patch(jump_to_else_pos, OP_JUMP_IF_NOT, start_of_else); - vm_bytecode_patch(jump_to_else_end_pos, OP_JUMP, end_of_else); - } - else if (command == vm_commands_sym_plot) - { - DEBUG("Emitting plot"); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - vm_bytecode_emit(OP_PLOT, 0); - } - else if (command == vm_commands_sym_line) - { - DEBUG("Emitting line"); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - TRY(vm_emit_exp()); - vm_bytecode_emit(OP_LINE, 0); - } - else if (command == vm_commands_sym_halt) - { - DEBUG("Emitting clear"); - vm_bytecode_emit(OP_HALT, 0); - } - else if (command == vm_commands_sym_clear) - { - DEBUG("Emitting clear"); - vm_bytecode_emit(OP_PUSH, white); - vm_bytecode_emit(OP_FILL, 0); - } - else if (command == vm_commands_sym_exit || command == vm_commands_sym_quit) - { - DEBUG("emitting exit command"); - vm_bytecode_emit(OP_EXIT, 0); - } - else if (command == vm_commands_sym_fill) - { - DEBUG("emitting exit command"); - TRY(vm_emit_exp()); // the color to fill the screen with - vm_bytecode_emit(OP_FILL, 0); - } - else if (did_read_all_input()) - { - DEBUG("Printing symbol value"); - if(command == NULL) return 1; - i64 var = vm_symbol_get_var(command); - if(0 > var) return 1; - console_newline(); - console_print_i64(vm_vars[var]); - } - else - { - console_error("Unrecognized command"); - return 1; - } - - return 0; -} - -void vm_load_cmd() -{ - vm_commands_selected = NULL; - if(vm_command_text_buffer_cursor == 0) return; - - DEBUGS(vm_command_text_buffer); - - i64 cmd_num = read_uint(); - u64* command = read_sym(); - if (command == vm_commands_sym_run) - { - vm_commands_selected = vm_commands_root; - return; - } - DEBUG("cmd_num\n"); - DEBUGI(cmd_num); - DEBUG(""); - u64** cmd; - if(cmd_num < 0) - { - DEBUG("Creating disposable cmd"); - cmd = vm_commands_alloc(cmd_num); - } - else - { - DEBUG("Retrieving cmd"); - cmd = vm_command_create(cmd_num); - } - - if(cmd == NULL) - { - DEBUG("Failed to allocate command"); - return; - } - - vm_commands_selected = cmd; - - if(command == NULL) command = read_sym(); - - if(vm_emit_cmd(command)) - { - if(cmd_num >= 0) vm_command_create(cmd_num); - else vm_command_free(cmd); - vm_commands_selected = NULL; - } - else if (cmd_num >= 0) - { - vm_commands_selected = NULL; - } - vm_command_text_buffer_clear(); -} - -i64 vm_pop() -{ - i64 val = vm_stack[--vm_stack_cursor]; - vm_stack[vm_stack_cursor] = 0; - return val; -} - -void vm_push(i64 v) -{ - vm_stack[vm_stack_cursor] = v; - ++vm_stack_cursor; -} - -#define BIN_OP(opcode, c_op) \ - else if (op == opcode) \ -{ \ - val2 = vm_pop(); \ - val1 = vm_pop(); \ - DEBUGS("OP: "); \ - DEBUGI(op); \ - DEBUGS("\n"); \ - DEBUGS("val1: "); \ - DEBUGI(val1); \ - DEBUGS("\n"); \ - DEBUGS("val2: "); \ - DEBUGI(val2); \ - DEBUGS("\n"); \ - i64 result = val1 c_op val2; \ - DEBUGS("result: "); \ - DEBUGI(result); \ - DEBUGS("\n"); \ - vm_push(result); \ -} - -#define PRINT_OP(op_str, op_name) else if(op == op_name) \ -{ \ - puts(op_str); \ -} - -void print_inst(u64 inst) -{ - u8 op = (u8)(inst >> 56); - u64 arg = (inst & (((u64)1<<56) - 1)); - puts("ints:"); - print_i64(inst); - puts("\n"); - puts("op:"); - print_i64(op); - puts("\n"); - puts("name:"); - if(0){} - PRINT_OP("OP_PUSH", OP_PUSH) - PRINT_OP("OP_SET_VAR", OP_SET_VAR) - PRINT_OP("OP_GET_VAR", OP_GET_VAR) - PRINT_OP("OP_JUMP", OP_JUMP) - PRINT_OP("OP_JUMP_IF", OP_JUMP_IF) - PRINT_OP("OP_JUMP_IF_NOT", OP_JUMP_IF_NOT) - PRINT_OP("OP_ADD", OP_ADD) - PRINT_OP("OP_SUB", OP_SUB) - PRINT_OP("OP_MULT", OP_MULT) - PRINT_OP("OP_DIV", OP_DIV) - PRINT_OP("OP_GT", OP_GT) - PRINT_OP("OP_LT", OP_LT) - PRINT_OP("OP_GT_EQ", OP_GT_EQ) - PRINT_OP("OP_LT_EQ", OP_LT_EQ) - PRINT_OP("OP_EQ", OP_EQ) - PRINT_OP("OP_NOT_EQ", OP_NOT_EQ) - PRINT_OP("OP_PRINT_INT", OP_PRINT_INT) - PRINT_OP("OP_GOTO", OP_GOTO) - PRINT_OP("OP_HALT", OP_HALT) - PRINT_OP("OP_FILL", OP_FILL) - PRINT_OP("OP_EXIT", OP_EXIT) - - puts("\n"); - puts("arg:"); - print_i64(arg); - puts("\n"); -} - -void print_insts(u64** cmd) -{ - u64* cmd_insts = cmd[VM_COMMANDS_INSTS_BUFFER]; - u64 cmd_size = (u64)cmd[VM_COMMANDS_CUR]; - puts("INSTRUCTION PRINTOUT \n"); - for(size_t inst_idx = 0; (inst_idx < cmd_size); ++inst_idx) - { - puts("--------------\n"); - u64 inst = cmd_insts[inst_idx]; - puts("idx:"); - print_i64(inst_idx); - puts("\n"); - print_inst(inst); - } - - puts("-- END INSTRUCTION PRINTOUT"); -} - -void vm_hand_control_back() -{ - vm_commands_selected = NULL; - vm_status = VM_STATUS_DONE; - console_print_ready(); - min_line_idx = line_idx; - console_redraw_commit(); -} - -void vm_exec() -{ - if(vm_commands_selected == NULL || vm_status == VM_STATUS_HALT) - { - vm_hand_control_back(); - return; - } - - vm_status = VM_STATUS_RUNNING; - i64 val1; - i64 val2; - u64 sleep = 0; - u64** cmd = vm_commands_selected; - vm_commands_selected = (u64**) cmd[VM_COMMANDS_NEXT]; - u64 cur_cmd_num = (u64)cmd[VM_COMMANDS_NUM]; - - u64* cmd_insts = cmd[VM_COMMANDS_INSTS_BUFFER]; - u64 cmd_size = (u64)cmd[VM_COMMANDS_CUR]; - - for(size_t inst_idx = 0; (inst_idx < cmd_size);) - { - u64 inst = cmd_insts[inst_idx]; - u8 op = (u8)(inst >> 56); - u64 arg = (inst & (((u64)1<<56) - 1)); - - // TODO check for overflow - if(op == OP_PUSH) vm_push(arg); - else if (op == OP_SET_VAR) vm_vars[arg] = vm_pop(); - else if (op == OP_GET_VAR) vm_push(vm_vars[arg]); - else if (op == OP_PRINT_INT) - { - console_newline(); - console_print_i64(vm_pop()); - } - else if (op == OP_GOTO) vm_commands_selected = vm_command_find(vm_pop()); - else if (op == OP_RAND) vm_push(rand()); - else if (op == OP_PRINT_STR) - { - u64* str = (u64)vm_vars[arg]; - console_newline(); - console_puts(str[SYM_META_STR]); - break; - } - else if (op == OP_SLEEP) - { - sleep = vm_pop(); - break; - } - else if (op == OP_HALT) - { - vm_hand_control_back(); - return; - } - else if (op == OP_HELP_ALL) - { - console_newline(); - console_puts("Commands: "); - console_newline(); - console_puts("LET GOTO IF PLOT LINE"); - console_newline(); - console_puts("CLEAR FILL RUN HALT EXIT SLEEP PRINT"); - console_newline(); - console_newline(); - console_puts("Builtin functions:"); - console_newline(); - console_puts("RAND"); - console_newline(); - console_newline(); - console_puts("Builtin variables:"); - console_newline(); - console_puts("BLUE RED GREEN BLACK"); - console_newline(); - console_puts("WHITE"); - console_newline(); - console_puts("CWIDTH(canvas width)"); - console_newline(); - console_puts("CHEIGHT(canvas height)"); - console_newline(); - console_newline(); - console_puts("Canvas size: "); - console_print_i64(canvas_width); - console_puts("X"); - console_print_i64(canvas_height); - console_newline(); - console_newline(); - console_puts("Use HELP {command or function} for more information"); - } - else if (op == OP_EXIT) - { - DEBUG("Exiting the program"); - exit(0); - } - else if (op == OP_FILL) - { - DEBUG("Filling the screen color"); - u32 color = vm_pop(); - canvas_fill(color); - console_redraw_all_text(); - } - else if (op == OP_JUMP) - { - if (arg > cmd_size) break; - DEBUG("Unconditionally jumping"); - inst_idx = arg; - continue; - } - else if (op == OP_JUMP_IF_NOT) - { - DEBUG("EXECUTING OP_JUMP_IF_NOT"); - if (arg > cmd_size) break; - if(!vm_pop()) - { - DEBUG("DETECTED A NOT SO jumping"); - inst_idx = arg; - continue; - } - } - else if (op == OP_PLOT) - { - u64 color = vm_pop(); - u64 y = vm_pop(); - u64 x = vm_pop(); - canvas_plot(x, y, color); - } - else if (op == OP_LINE) - { - u32 color = (u32)vm_pop(); - u32 y1 = (u32)vm_pop(); - u32 x1 = (u32)vm_pop(); - u32 y0 = (u32)vm_pop(); - u32 x0 = (u32)vm_pop(); - if(canvas_coord_gaurd(x0, y0)) break; - if(canvas_coord_gaurd(x1, y1)) break; - draw_line((u32*)frame_buffer, FRAME_WIDTH, FRAME_HEIGHT, console_width + x0, y0, console_width + x1, y1, color); - } - BIN_OP(OP_ADD, +) - BIN_OP(OP_SUB, -) - BIN_OP(OP_MULT, *) - BIN_OP(OP_DIV, /) - BIN_OP(OP_GT, >) - BIN_OP(OP_LT, <) - BIN_OP(OP_GT_EQ, >=) - BIN_OP(OP_LT_EQ, <=) - BIN_OP(OP_EQ, ==) - BIN_OP(OP_NOT_EQ, !=) - BIN_OP(OP_MOD, %) - else - { - DEBUG("unrecognized command"); - vm_hand_control_back(); - return; - } - DEBUG("executing inst"); - ++inst_idx; - } - - time_delay_cb(sleep, vm_exec); -}