From 1f1c9c73647462169ef7a9548b168d6605fa6cbb Mon Sep 17 00:00:00 2001 From: Peter Weingartner Date: Wed, 3 Jul 2024 20:40:00 -0400 Subject: [PATCH] ASCII character support for F256k and BREAK key --- src/dev/kbd_f256k.c | 407 +++++++++++++++++++++++++++++++++++++++++++- src/dev/kbd_f256k.h | 45 +++++ src/toolbox.c | 39 +++-- 3 files changed, 469 insertions(+), 22 deletions(-) diff --git a/src/dev/kbd_f256k.c b/src/dev/kbd_f256k.c index 16148da..dddb18b 100644 --- a/src/dev/kbd_f256k.c +++ b/src/dev/kbd_f256k.c @@ -9,16 +9,18 @@ * */ +#include +#include +#include +#include + #include "log.h" #include "ring_buffer.h" #include "dev/kbd_f256k.h" #include "F256/via_f256.h" -#include -#include - -#include #include "uart.h" #include "gabe_reg.h" +#include "simpleio.h" // // Constants @@ -41,6 +43,13 @@ #define KBD_MOD_OS 0x40 #define KBD_MOD_MENU 0x80 +/* + * Special key scan codes + */ + +#define KEY_C 0x2e +#define KEY_BREAK 0x61 + // // Map a key's matrix position to its scan code (FoenixMCP scan codes are used here) // @@ -66,6 +75,173 @@ static const uint8_t kbd_scan_codes[KBD_ROWS][KBD_COLUMNS] = { {0x02, 0x01, 0x1d, 0x03, 0x39, 0x5b, 0x10, 0x61, 0x00} }; +/* + * Mapping of "codepoints" 0x80 - 0x98 (function keys, etc) + * to ANSI escape codes + */ +const char * ansi_keys[] = { + "1", /* HOME */ + "2", /* INS */ + "3", /* DELETE */ + "4", /* END */ + "5", /* PgUp */ + "6", /* PgDn */ + "A", /* Up */ + "B", /* Left */ + "C", /* Right */ + "D", /* Down */ + "11", /* F1 */ + "12", /* F2 */ + "13", /* F3 */ + "14", /* F4 */ + "15", /* F5 */ + "17", /* F6 */ + "18", /* F7 */ + "19", /* F8 */ + "20", /* F9 */ + "21", /* F10 */ + "23", /* F11 */ + "24", /* F12 */ + "30", /* MONITOR */ + "31", /* CTX SWITCH */ + "32" /* MENU HELP */ +}; + +/* + * US keyboard layout scancode translation tables + */ + +#define POUND 0x9c + +const char kbd_256k_layout[] = { + // Unmodified + 0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */ + '7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */ + 'o', 'p', '[', ']', 0x0D, 0x00, 'a', 's', /* 0x18 - 0x1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 0x20 - 0x27 */ + 0x27, '`', 0x00, '\\', 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */ + 'b', 'n', 'm', ',', '.', '/', 0x00, '*', /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */ + 0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */ + 0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + // Shifted + 0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */ + '&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 0x10 - 0x17 */ + 'O', 'P', '{', '}', 0x0A, 0x00, 'A', 'S', /* 0x18 - 0x1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 0x20 - 0x27 */ + 0x22, '~', 0x00, '|', 'Z', 'X', 'C', 'V', /* 0x28 - 0x2F */ + 'B', 'N', 'M', '<', '>', '?', 0x00, 0x00, /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */ + 0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */ + 0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + // Control + 0x00, 0x1B, '1', '2', '3', '4', '5', 0x1E, /* 0x00 - 0x07 */ + '7', '8', '9', '0', 0x1F, '=', 0x08, 0x09, /* 0x08 - 0x0F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* 0x10 - 0x17 */ + 0x0F, 0x10, 0x1B, 0x1D, 0x0A, 0x00, 0x01, 0x13, /* 0x18 - 0x1F */ + 0x04, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, ';', /* 0x20 - 0x27 */ + 0x22, '`', 0x00, '\\', 0x1A, 0x18, 0x03, 0x16, /* 0x28 - 0x2F */ + 0x02, 0x0E, 0x0D, ',', '.', 0x1C, 0x00, 0x00, /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */ + 0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */ + 0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + + // Control-Shift + 0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */ + '&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* 0x10 - 0x17 */ + 0x0F, 0x10, 0x1B, 0x1D, 0x0A, 0x00, 0x01, 0x13, /* 0x18 - 0x1F */ + 0x04, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, ';', /* 0x20 - 0x27 */ + 0x22, '`', 0x00, '\\', 0x1A, 0x18, 0x03, 0x16, /* 0x28 - 0x2F */ + 0x02, 0x0E, 0x0D, ',', '.', 0x1C, 0x00, 0x00, /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */ + 0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */ + 0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + // Capslock + 0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */ + '7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 0x10 - 0x17 */ + 'O', 'P', '[', ']', 0x0D, 0x00, 'A', 'S', /* 0x18 - 0x1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 0x20 - 0x27 */ + 0x27, '`', 0x00, '\\', 'Z', 'X', 'C', 'V', /* 0x28 - 0x2F */ + 'B', 'N', 'M', ',', '.', '/', 0x00, 0x00, /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */ + '2', '3', '0', '.', 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + // Caps-Shift + 0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */ + '&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */ + 'o', 'p', '{', '}', 0x0A, 0x00, 'a', 's', /* 0x18 - 0x1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ':', /* 0x20 - 0x27 */ + 0x22, 0x00, 0x00, 0x00, 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */ + 'b', 'n', 'm', '<', '>', '?', 0x00, 0x00, /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */ + '2', '3', '0', '.', 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ + + // ALT + 0x00, 0x1B, '1', '2', '3', POUND, '5', '6', /* 0x00 - 0x07 */ + '~', '`', '|', '\\', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */ + 'o', 'p', '[', ']', 0x0D, 0x00, 'a', 's', /* 0x18 - 0x1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 0x20 - 0x27 */ + 0x27, 0x00, 0x00, 0x00, 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */ + 'b', 'n', 'm', ',', '.', '/', 0x00, '*', /* 0x30 - 0x37 */ + 0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */ + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */ + 0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */ + 0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */ + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */ + 0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */ + 0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */ +}; + // // Driver variables // @@ -73,8 +249,20 @@ static const uint8_t kbd_scan_codes[KBD_ROWS][KBD_COLUMNS] = { static uint16_t kbd_stat[KBD_MATRIX_SIZE]; static short counter = 0; static uint8_t last_press = 0; -static t_word_ring scan_code_buffer; -static uint8_t modifiers; +static t_word_ring scan_code_buffer; +static t_word_ring char_buffer; +static uint8_t modifiers = 0; +static bool break_pressed = 0; + +/* Scan code to character lookup tables */ + +static char keys_unmodified[128]; +static char keys_shift[128]; +static char keys_control[128]; +static char keys_control_shift[128]; +static char keys_caps[128]; +static char keys_caps_shift[128]; +static char keys_alt[128]; /** * @brief Get the keys selected in a given row @@ -177,6 +365,12 @@ static void kbd_process_key(short column, short row, bool is_pressed) { last_press = scan_code; } + // Set the break flag if the RUN/STOP or CTRL-C key was pressed + if ((scan_code == KEY_BREAK) || + ((scan_code == KEY_C) && ((modifiers & KBD_MOD_CTRL) != 0))) { + break_pressed = true; + } + if (!rb_word_full(&scan_code_buffer)) { rb_word_put(&scan_code_buffer, (modifiers << 8) | scan_code); } @@ -224,6 +418,204 @@ void kbd_handle_irq() { } } +/* + * Catch special keys and convert them to their ANSI terminal codes + * + * Characters 0x80 - 0x98 are reserved for function keys, arrow keys, etc. + * This function maps them to the ANSI escape codes + * + * Inputs: + * modifiers = the current modifier bit flags (ALT, CTRL, META, etc) + * c = the character found from the scan code. + */ +static unsigned char kbd_to_ansi(unsigned char modifiers, unsigned char c) { + if ((c >= 0x80) && (c <= 0x98)) { + /* The key is a function key or a special control key */ + const char * ansi_key = ansi_keys[c - 0x80]; + const char * sequence; + short modifiers_after = 0; + + // Figure out if the modifiers come before or after the sequence code + if (isdigit(ansi_key[0])) { + // Sequence is numeric, modifiers come after + modifiers_after = 1; + } + + // After ESC, all sequences have [ + rb_word_put(&char_buffer, '['); + + if (modifiers_after) { + // Sequence is numberic, get the expanded sequence and put it in the queue + for (sequence = ansi_keys[c - 0x80]; *sequence != 0; sequence++) { + rb_word_put(&char_buffer, *sequence); + } + } + + // Check to see if we need to send a modifier sequence + if (modifiers & (KBD_MOD_SHIFT | KBD_MOD_CTRL | KBD_MOD_ALT | KBD_MOD_OS)) { + unsigned char code_bcd; + short modifier_code = 0; + short i; + + if (modifiers_after) { + // Sequence is numeric, so put modifiers after the sequence and a semicolon + rb_word_put(&char_buffer, ';'); + } + + modifier_code = ((modifiers >> 3) & 0x1F) + 1; + code_bcd = i_to_bcd(modifier_code); + + if (code_bcd & 0xF0) { + rb_word_put(&char_buffer, ((code_bcd & 0xF0) >> 4) + '0'); + } + rb_word_put(&char_buffer, (code_bcd & 0x0F) + '0'); + } + + if (!modifiers_after) { + // Sequence is a letter code + rb_word_put(&char_buffer, ansi_key[0]); + } else { + // Sequence is numeric, close it with a tilda + rb_word_put(&char_buffer, '~'); + } + + return 0x1B; /* Start the sequence with an escape */ + + } else if (c == 0x1B) { + /* ESC should be doubled, to distinguish from the start of an escape sequence */ + rb_word_put(&char_buffer, 0x1B); + return c; + + } else { + /* Not a special key: return the character unmodified */ + + return c; + } +} + +/* + * Try to get a character from the keyboard... + * + * Returns: + * the next character to be read from the keyboard (0 if none available) + */ +char kbd_getc() { + if (!rb_word_empty(&char_buffer)) { + // If there is a character waiting in the character buffer, return it... + return (char)rb_word_get(&char_buffer); + + } else { + // Otherwise, we need to check the scan code queue... + unsigned short raw_code = kbd_get_scancode(); + while (raw_code != 0) { + if ((raw_code & 0x80) == 0) { + // If it's a make code, let's try to look it up... + unsigned char modifiers = (raw_code >> 8) & 0xff; // Get the modifiers + unsigned char scan_code = raw_code & 0x7f; // Get the base code for the key + + // Check the modifiers to see what we should lookup... + + if ((modifiers & (KBD_MOD_ALT | KBD_MOD_SHIFT | KBD_MOD_CTRL | KBD_LOCK_CAPS)) == 0) { + // No modifiers... just return the base character + return kbd_to_ansi(modifiers, keys_unmodified[scan_code]); + + } else if (modifiers & KBD_MOD_ALT) { + return kbd_to_ansi(modifiers, keys_alt[scan_code]); + + } else if (modifiers & KBD_MOD_CTRL) { + // If CTRL is pressed... + if (modifiers & KBD_MOD_SHIFT) { + // If SHIFT is also pressed, return CTRL-SHIFT form + return kbd_to_ansi(modifiers, keys_control_shift[scan_code]); + + } else { + // Otherwise, return just CTRL form + return kbd_to_ansi(modifiers, keys_control[scan_code]); + } + + } else if (modifiers & KBD_LOCK_CAPS) { + // If CAPS is locked... + if (modifiers & KBD_MOD_SHIFT) { + // If SHIFT is also pressed, return CAPS-SHIFT form + return kbd_to_ansi(modifiers, keys_caps_shift[scan_code]); + + } else { + // Otherwise, return just CAPS form + return kbd_to_ansi(modifiers, keys_caps[scan_code]); + } + } else { + // SHIFT is pressed, return SHIFT form + return kbd_to_ansi(modifiers, keys_shift[scan_code]); + } + } + + // If we reach this point, it wasn't a useful scan-code... + // So try to fetch another + raw_code = kbd_get_scancode(); + } + + // If we reach this point, there are no useful scan codes + return 0; + } +} + +/* + * Check to see if a BREAK code has been pressed recently + * If so, return true and reset the internal flag. + * + * BREAK will be RUN/STOP or CTRL-C on the F256K + * + * Returns: + * true if a BREAK has been pressed since the last check + */ +bool kbd_break() { + bool result = break_pressed; + break_pressed = 0; + return result; +} + +/* + * Set the keyboard translation tables + * + * The translation tables provided to the keyboard consist of eight + * consecutive tables of 128 characters each. Each table maps from + * the MAKE scan code of a key to its appropriate 8-bit character code. + * + * The tables included must include, in order: + * - UNMODIFIED: Used when no modifier keys are pressed or active + * - SHIFT: Used when the SHIFT modifier is pressed + * - CTRL: Used when the CTRL modifier is pressed + * - CTRL-SHIFT: Used when both CTRL and SHIFT are pressed + * - CAPSLOCK: Used when CAPSLOCK is down but SHIFT is not pressed + * - CAPSLOCK-SHIFT: Used when CAPSLOCK is down and SHIFT is pressed + * - ALT: Used when only ALT is presse + * - ALT-SHIFT: Used when ALT is pressed and either CAPSLOCK is down + * or SHIFT is pressed (but not both) + * + * Inputs: + * tables = pointer to the keyboard translation tables + */ +short SYSTEMCALL kbd_layout(const char * tables) { + short i; + + for (i = 0; i < 128; i++) { + keys_unmodified[i] = tables[i]; + keys_shift[i] = tables[i + 128]; + keys_control[i] = tables[i + 256]; + // if (keys_control[i] == 0x03) { + // // We have set the scan code for CTRL-C? + // g_kbdmo_break_sc = i; + // } + // Check for CTRL-C + keys_control_shift[i] = tables[i + 384]; + keys_caps[i] = tables[i + 512]; + keys_caps_shift[i] = tables[i + 640]; + keys_alt[i] = tables[i + 768]; + } + + return 0; +} + /* * Initialize the matrix keyboard * @@ -255,5 +647,8 @@ short kbd_init() { // Set up and clear out the buffer for the scan codes rb_word_init(&scan_code_buffer); + // Set up the layout of the F256k keyboard + kbd_layout(kbd_256k_layout); + return 1; } diff --git a/src/dev/kbd_f256k.h b/src/dev/kbd_f256k.h index fc23115..a3608e8 100644 --- a/src/dev/kbd_f256k.h +++ b/src/dev/kbd_f256k.h @@ -12,6 +12,9 @@ #ifndef __kbd_f256k_h__ #define __kbd_f256k_h__ +#include +#include "sys_macros.h" + /** * @brief Handle an IRQ to query the keyboard * @@ -26,6 +29,48 @@ extern void kbd_handle_irq(); */ extern unsigned short kbd_get_scancode(); +/* + * Check to see if a BREAK code has been pressed recently + * If so, return true and reset the internal flag. + * + * BREAK will be RUN/STOP or CTRL-C on the F256K + * + * Returns: + * true if a BREAK has been pressed since the last check + */ +extern bool kbd_break(); + +/* + * Try to get a character from the keyboard... + * + * Returns: + * the next character to be read from the keyboard (0 if none available) + */ +extern char kbd_getc(); + +/* + * Set the keyboard translation tables + * + * The translation tables provided to the keyboard consist of eight + * consecutive tables of 128 characters each. Each table maps from + * the MAKE scan code of a key to its appropriate 8-bit character code. + * + * The tables included must include, in order: + * - UNMODIFIED: Used when no modifier keys are pressed or active + * - SHIFT: Used when the SHIFT modifier is pressed + * - CTRL: Used when the CTRL modifier is pressed + * - CTRL-SHIFT: Used when both CTRL and SHIFT are pressed + * - CAPSLOCK: Used when CAPSLOCK is down but SHIFT is not pressed + * - CAPSLOCK-SHIFT: Used when CAPSLOCK is down and SHIFT is pressed + * - ALT: Used when only ALT is presse + * - ALT-SHIFT: Used when ALT is pressed and either CAPSLOCK is down + * or SHIFT is pressed (but not both) + * + * Inputs: + * tables = pointer to the keyboard translation tables + */ +extern SYSTEMCALL short kbd_layout(const char * tables); + /* * Initialize the matrix keyboard * diff --git a/src/toolbox.c b/src/toolbox.c index 8bda566..e7dc3fb 100644 --- a/src/toolbox.c +++ b/src/toolbox.c @@ -184,15 +184,16 @@ void initialize() { INFO("Real time clock initialized"); t_time time; - time.year = 2024; - time.month = 6; - time.day = 24; - time.hour = 22; - time.minute = 0; - time.second = 0; - rtc_set_time(&time); + // time.year = 2024; + // time.month = 7; + // time.day = 3; + // time.hour = 16; + // time.minute = 05; + // time.second = 0; + // rtc_set_time(&time); rtc_get_time(&time); + printf("%04d-%02d-%02d %02d:%02d\n", time.year, time.month, time.day, time.hour, time.minute); INFO3("%04d-%02d-%02d", time.year, time.month, time.day); // target_jiffies = sys_time_jiffies() + 300; /* 5 seconds minimum */ @@ -259,11 +260,11 @@ void initialize() { } #endif -// // if (res = uart_install()) { -// // log_num(LOG_ERROR, "FAILED: serial port initialization", res); -// // } else { -// // log(LOG_INFO, "Serial ports initialized."); -// // } +// if (res = uart_install()) { +// log_num(LOG_ERROR, "FAILED: serial port initialization", res); +// } else { +// log(LOG_INFO, "Serial ports initialized."); +// } // if ((res = fsys_init())) { // log_num(LOG_ERROR, "FAILED: file system initialization", res); @@ -285,15 +286,21 @@ int main(int argc, char * argv[]) { initialize(); + printf("Hello, world!\n"); + printf("This is a test.\n"); + kbd_init(); - while (1) { + printf("\n> "); + while (!kbd_break()) { kbd_handle_irq(); - unsigned short scan_code = kbd_get_scancode(); - if (scan_code != 0) { - INFO1("0x%04X ", scan_code); + char c = kbd_getc(); + if (c != 0) { + txt_put(0, c); } } + printf("\nDone.\n"); + // Attempt to start up the user code // log(LOG_INFO, "Looking for user startup code:"); // boot_launch();