F256jr PS/2 Keyboard Support Added
This commit is contained in:
parent
fd80b729bd
commit
887c04a86b
|
@ -37,7 +37,14 @@ else ifeq ($(UNIT),F256)
|
|||
AS=as65816
|
||||
AR=nlib
|
||||
|
||||
SRCS_FOR_UNIT=txt_f256.c kbd_f256k.c indicators_c256.c interrupts_f256.c sdc_f256.c # timers_c256.c
|
||||
SRCS_FOR_UNIT=txt_f256.c kbd_f256.c kbd_f256jr.c indicators_c256.c interrupts_f256.c sdc_f256.c # timers_c256.c
|
||||
CFLAGS_FOR_UNIT=-DMODEL=2 -DCPU=255 --code-model large --data-model large # --target Foenix
|
||||
else ifeq ($(UNIT),F256K)
|
||||
CC=cc65816
|
||||
AS=as65816
|
||||
AR=nlib
|
||||
|
||||
SRCS_FOR_UNIT=txt_f256.c kbd_f256.c kbd_f256k.c indicators_c256.c interrupts_f256.c sdc_f256.c # timers_c256.c
|
||||
CFLAGS_FOR_UNIT=-DMODEL=2 -DCPU=255 --code-model large --data-model large # --target Foenix
|
||||
endif
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#if MODEL == MODEL_FOENIX_A2560K
|
||||
#include "dev/kbd_mo.h"
|
||||
#elif MODEL == MODEL_FOENIX_F256
|
||||
#include "dev/kbd_f256jr.h"
|
||||
#elif MODEL == MODEL_FOENIX_F256K
|
||||
#include "dev/kbd_f256k.h"
|
||||
#endif
|
||||
|
|
419
src/dev/kbd_f256.c
Normal file
419
src/dev/kbd_f256.c
Normal file
|
@ -0,0 +1,419 @@
|
|||
/**
|
||||
* @file kbd_f256.h
|
||||
* @author your name (you@domain.com)
|
||||
* @brief Common code for F256 keyboards to convert scancodes to characters
|
||||
* @version 0.1
|
||||
* @date 2024-07-12
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
|
||||
#include "log_level.h"
|
||||
#define DEFAULT_LOG_LEVEL LOG_ERROR
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "kbd_f256.h"
|
||||
#include "kbd_f256jr.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "simpleio.h"
|
||||
#include "sys_macros.h"
|
||||
#include "txt_screen.h"
|
||||
|
||||
/*
|
||||
* Modifier bit flags
|
||||
*/
|
||||
|
||||
#define KBD_LOCK_SCROLL 0x01
|
||||
#define KBD_LOCK_NUM 0x02
|
||||
#define KBD_LOCK_CAPS 0x04
|
||||
#define KBD_MOD_SHIFT 0x08
|
||||
#define KBD_MOD_CTRL 0x10
|
||||
#define KBD_MOD_ALT 0x20
|
||||
#define KBD_MOD_OS 0x40
|
||||
#define KBD_MOD_MENU 0x80
|
||||
|
||||
/*
|
||||
* 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
|
||||
//
|
||||
|
||||
static t_word_ring char_buffer;
|
||||
|
||||
/* 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];
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the keyboard scancode to character converter.
|
||||
*
|
||||
*/
|
||||
void kbd_init() {
|
||||
// Initialize the low level scancode driver
|
||||
kbd_sc_init();
|
||||
|
||||
// Initialize character ring buffer
|
||||
rb_word_init(&char_buffer);
|
||||
|
||||
// Set up the layout of the F256k keyboard
|
||||
kbd_layout(kbd_256k_layout);
|
||||
}
|
||||
|
60
src/dev/kbd_f256.h
Normal file
60
src/dev/kbd_f256.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file kbd_f256.h
|
||||
* @author your name (you@domain.com)
|
||||
* @brief Common code for F256 keyboards to convert scancodes to characters
|
||||
* @version 0.1
|
||||
* @date 2024-07-12
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __kbd_f256_h__
|
||||
#define __kbd_f256_h__
|
||||
|
||||
#if MODEL == MODEL_FOENIX_F256
|
||||
#include "kbd_f256jr.h"
|
||||
#elif MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2
|
||||
#include "kbd_f256k.h"
|
||||
#endif
|
||||
|
||||
#include "sys_macros.h"
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* @brief Initialize the keyboard scancode to character converter.
|
||||
*
|
||||
*/
|
||||
extern void kbd_init();
|
||||
|
||||
#endif
|
464
src/dev/kbd_f256jr.c
Normal file
464
src/dev/kbd_f256jr.c
Normal file
|
@ -0,0 +1,464 @@
|
|||
/**
|
||||
* @file kbd_f256jr.h
|
||||
* @author your name (you@domain.com)
|
||||
* @brief Driver for the F256jr PS/2 keyboard
|
||||
* @version 0.1
|
||||
* @date 2024-06-17
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __kbd_f256jr_h__
|
||||
#define __kbd_f256jr_h__
|
||||
|
||||
#include "log_level.h"
|
||||
#ifndef DEFAULT_LOG_LEVEL
|
||||
#define DEFAULT_LOG_LEVEL LOG_ERROR
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "log.h"
|
||||
#include "ps2_reg.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "sys_macros.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
||||
/*
|
||||
* Modifier bit flags
|
||||
*/
|
||||
|
||||
#define KBD_LOCK_SCROLL 0x01
|
||||
#define KBD_LOCK_NUM 0x02
|
||||
#define KBD_LOCK_CAPS 0x04
|
||||
#define KBD_MOD_SHIFT 0x08
|
||||
#define KBD_MOD_CTRL 0x10
|
||||
#define KBD_MOD_ALT 0x20
|
||||
#define KBD_MOD_OS 0x40
|
||||
#define KBD_MOD_MENU 0x80
|
||||
|
||||
/*
|
||||
* Special PS/2 byte codes
|
||||
*/
|
||||
|
||||
#define KBD_PS2_SC_LSHIFT 0x12
|
||||
#define KBD_PS2_SC_RSHIFT 0x59
|
||||
#define KBD_PS2_SC_CAPS 0x58
|
||||
#define KBD_PS2_SC_LCTRL 0x14
|
||||
#define KBD_PS2_SC_RCTRL 0x14
|
||||
#define KBD_PS2_SC_LALT 0x11
|
||||
#define KBD_PS2_SC_RALT 0x11
|
||||
#define KBD_PS2_SC_NUM 0x77
|
||||
#define KBD_PS2_SC_LGUI 0x1f
|
||||
#define KBD_PS2_SC_RGUI 0x27
|
||||
|
||||
/*
|
||||
* Special Foenix key scan codes
|
||||
*/
|
||||
|
||||
#define KEY_C 0x2e
|
||||
#define KEY_BREAK 0x61
|
||||
|
||||
/**
|
||||
* @brief Translation from base set 2 scancodes to Foenix scancodes
|
||||
*
|
||||
*/
|
||||
const short kbd_ps2_default_sc[] = {
|
||||
0x00, 0x43, 0x00, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 0x00, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x00, // 0x00 - 0x0f
|
||||
0x00, 0x38, 0x2a, 0x00, 0x1d, 0x10, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x00, // 0x10 - 0x1f
|
||||
0x00, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x00, 0x00, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x00, // 0x20 - 0x2f
|
||||
0x00, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x00, 0x00, 0x00, 0x32, 0x24, 0x16, 0x08, 0x09, 0x00, // 0x30 - 0x3f
|
||||
0x00, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x00, 0x00, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x00, // 0x40 - 0x4f
|
||||
0x00, 0x00, 0x28, 0x00, 0x1a, 0x0d, 0x00, 0x00, 0x3a, 0x36, 0x1c, 0x1b, 0x00, 0x2b, 0x00, 0x00, // 0x50 - 0x5f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 - 0x6f
|
||||
0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 0x57, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x7f
|
||||
0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x8f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x9f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 - 0xaf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 - 0xbf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 - 0xcf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 - 0xdf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 - 0xef
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0 - 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Translation from set 2 E0 prefixed scancodes to Foenix scancodes
|
||||
*
|
||||
*/
|
||||
const short kbd_ps2_e0_sc[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x0f
|
||||
0x00, 0x5c, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, // 0x10 - 0x1f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, // 0x20 - 0x2f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 - 0x3f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 - 0x4f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x5f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x69, 0x63, 0x00, 0x00, 0x00, // 0x60 - 0x6f
|
||||
0x62, 0x65, 0x6a, 0x00, 0x6b, 0x68, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x64, 0x00, 0x00, // 0x70 - 0x7f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x8f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x9f
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 - 0xaf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 - 0xbf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 - 0xcf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 - 0xdf
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 - 0xef
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0 - 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief States of the keyboard engine
|
||||
*
|
||||
*/
|
||||
enum kbd_state_e {
|
||||
kbd_state_default = 0,
|
||||
kbd_state_e0,
|
||||
kbd_state_e0f0,
|
||||
kbd_state_f0,
|
||||
kbd_state_e1,
|
||||
kbd_state_e114,
|
||||
kbd_state_e11477,
|
||||
kbd_state_e11477e1,
|
||||
kbd_state_e11477e1f0,
|
||||
kbd_state_e11477e1f014,
|
||||
kbd_state_e11477e1f014f0,
|
||||
kbd_state_e11477e1f014f077
|
||||
};
|
||||
|
||||
//
|
||||
// Module variables
|
||||
//
|
||||
|
||||
static enum kbd_state_e kbd_state = kbd_state_default;
|
||||
static t_word_ring scan_code_buffer;
|
||||
static t_word_ring char_buffer;
|
||||
static uint8_t modifiers = 0;
|
||||
static bool break_pressed = false;
|
||||
|
||||
//
|
||||
// Code
|
||||
//
|
||||
|
||||
static void kbd_send_cmd(uint8_t byte) {
|
||||
uint8_t status = 0;
|
||||
|
||||
*PS2_OUT = byte;
|
||||
*PS2_CTRL |= PS2_CTRL_KBD_WR;
|
||||
|
||||
do {
|
||||
status = *PS2_STAT;
|
||||
} while ((status & (PS2_STAT_KBD_ACK | PS2_STAT_KBD_NAK)) == 0);
|
||||
|
||||
*PS2_CTRL &= ~PS2_CTRL_KBD_WR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enqueue the scancode into the keyboard scancode buffer with modifiers added
|
||||
*
|
||||
* @param scancode the base scancode to enqueue
|
||||
* @param is_make true if the byte is a make code, false if it's a break
|
||||
*/
|
||||
static void kbd_enqueue_scancode(short scancode, bool is_make) {
|
||||
if (is_make) {
|
||||
// CTRL-C or CTRL-PAUSE trigger a break
|
||||
if (modifiers & KBD_MOD_CTRL) {
|
||||
if (scancode == KEY_C) {
|
||||
break_pressed = true;
|
||||
}
|
||||
} else if (modifiers & KBD_MOD_ALT) {
|
||||
if (scancode == KEY_BREAK) {
|
||||
break_pressed = true;
|
||||
}
|
||||
}
|
||||
rb_word_put(&scan_code_buffer, modifiers << 8 | (scancode & 0x00ff));
|
||||
|
||||
} else {
|
||||
rb_word_put(&scan_code_buffer, modifiers << 8 | (scancode & 0x00ff) | 0x0080);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the special tracking for modifier and lock keys
|
||||
*
|
||||
* @param modifier the modifier flag to either toggle or set/clear
|
||||
* @param is_make true if the byte is a make code, false if it's a break
|
||||
*/
|
||||
static void kbd_process_modifier(short modifier, bool is_make) {
|
||||
switch(modifier) {
|
||||
case KBD_MOD_SHIFT:
|
||||
case KBD_MOD_CTRL:
|
||||
case KBD_MOD_ALT:
|
||||
if (is_make) {
|
||||
modifiers |= modifier;
|
||||
} else {
|
||||
modifiers &= ~modifier;
|
||||
}
|
||||
break;
|
||||
|
||||
case KBD_LOCK_CAPS:
|
||||
case KBD_LOCK_NUM:
|
||||
if (!is_make) {
|
||||
modifiers ^= modifier;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle a set 2 default scancode byte
|
||||
*
|
||||
* @param byte_code the set 2 scancode to handle
|
||||
* @param is_make true if the byte is a make code, false if it's a break
|
||||
*/
|
||||
static void kbd_process_bytecode(uint8_t byte_code, bool is_make) {
|
||||
// Process modifier keys
|
||||
switch(byte_code) {
|
||||
case KBD_PS2_SC_LSHIFT:
|
||||
case KBD_PS2_SC_RSHIFT:
|
||||
// Shift keys
|
||||
kbd_process_modifier(KBD_MOD_SHIFT, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_CAPS:
|
||||
// Caps lock key
|
||||
kbd_process_modifier(KBD_LOCK_CAPS, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_LCTRL:
|
||||
// CTRL Key
|
||||
kbd_process_modifier(KBD_MOD_CTRL, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_LALT:
|
||||
// Alt Key
|
||||
kbd_process_modifier(KBD_MOD_ALT, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_NUM:
|
||||
// Number lock key
|
||||
kbd_process_modifier(KBD_LOCK_NUM, is_make);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Translate PS/2 scancode to Foenix scancode
|
||||
short scancode = kbd_ps2_default_sc[byte_code];
|
||||
if (scancode) {
|
||||
kbd_enqueue_scancode(scancode, is_make);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle a set 2 E0-prefixed scancode byte
|
||||
*
|
||||
* @param byte_code the set 2 E0-prefixed scancode to handle
|
||||
* @param is_make true if the byte is a make code, false if it's a break
|
||||
*/
|
||||
static void kbd_process_e0_bytecode(uint8_t byte_code, bool is_make) {
|
||||
// Process modifier keys
|
||||
switch(byte_code) {
|
||||
case KBD_PS2_SC_LGUI:
|
||||
case KBD_PS2_SC_RGUI:
|
||||
// GUI key
|
||||
kbd_process_modifier(KBD_MOD_OS, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_RCTRL:
|
||||
// CTRL Key
|
||||
kbd_process_modifier(KBD_MOD_CTRL, is_make);
|
||||
break;
|
||||
|
||||
case KBD_PS2_SC_RALT:
|
||||
// Alt Key
|
||||
kbd_process_modifier(KBD_MOD_ALT, is_make);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Translate PS/2 scancode with the E0 prefix to Foenix scancode
|
||||
short scancode = kbd_ps2_e0_sc[byte_code];
|
||||
if (scancode) {
|
||||
kbd_enqueue_scancode(scancode, is_make);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the bytecodes that come in from the PS/2 keyboard. Walk through the state machine for E0, F0, and E1 prefixes
|
||||
*
|
||||
* @param byte_code the raw bytes from the PS/2 interface
|
||||
*/
|
||||
static void kbd_process_set2_bytecode(uint8_t byte_code) {
|
||||
switch(kbd_state) {
|
||||
case kbd_state_default:
|
||||
switch(byte_code) {
|
||||
case 0xe0:
|
||||
kbd_state = kbd_state_e0;
|
||||
break;
|
||||
|
||||
case 0xf0:
|
||||
kbd_state = kbd_state_f0;
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
kbd_state = kbd_state_e1;
|
||||
break;
|
||||
|
||||
default:
|
||||
kbd_process_bytecode(byte_code, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e0:
|
||||
if (byte_code == 0xf0) {
|
||||
kbd_state = kbd_state_e0f0;
|
||||
} else {
|
||||
kbd_process_e0_bytecode(byte_code, true);
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_f0:
|
||||
kbd_process_bytecode(byte_code, false);
|
||||
kbd_state = kbd_state_default;
|
||||
break;
|
||||
|
||||
case kbd_state_e0f0:
|
||||
kbd_process_e0_bytecode(byte_code, false);
|
||||
kbd_state = kbd_state_default;
|
||||
break;
|
||||
|
||||
case kbd_state_e1:
|
||||
if (byte_code == 0x14) {
|
||||
kbd_state = kbd_state_e114;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e114:
|
||||
if (byte_code == 0x77) {
|
||||
kbd_state = kbd_state_e11477;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e11477:
|
||||
if (byte_code == 0xe1) {
|
||||
kbd_state = kbd_state_e11477e1;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e11477e1:
|
||||
if (byte_code == 0xf0) {
|
||||
kbd_state = kbd_state_e11477e1f0;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e11477e1f0:
|
||||
if (byte_code == 0x14) {
|
||||
kbd_state = kbd_state_e11477e1f014;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e11477e1f014:
|
||||
if (byte_code == 0xf0) {
|
||||
kbd_state = kbd_state_e11477e1f014f0;
|
||||
} else {
|
||||
kbd_state = kbd_state_default;
|
||||
}
|
||||
break;
|
||||
|
||||
case kbd_state_e11477e1f014f0:
|
||||
if (byte_code == 0x77) {
|
||||
kbd_enqueue_scancode(0x61, true);
|
||||
}
|
||||
kbd_state = kbd_state_default;
|
||||
break;
|
||||
|
||||
default:
|
||||
kbd_state = kbd_state_default;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle an IRQ to query the keyboard
|
||||
*
|
||||
*/
|
||||
void kbd_handle_irq() {
|
||||
// Check to see if there is a keyboard bytecode waiting... process it if so
|
||||
if ((*PS2_STAT & PS2_STAT_KBD_EMP) == 0) {
|
||||
kbd_process_set2_bytecode(*PS2_KBD_IN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to retrieve the next scancode from the keyboard.
|
||||
*
|
||||
* Returns:
|
||||
* The next scancode to be processed, 0 if nothing.
|
||||
*/
|
||||
unsigned short kbd_get_scancode() {
|
||||
if (!rb_word_empty(&scan_code_buffer)) {
|
||||
return rb_word_get(&scan_code_buffer);
|
||||
} else {
|
||||
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 CTRL-PAUSE or CTRL-C on the F256jr
|
||||
*
|
||||
* Returns:
|
||||
* true if a BREAK has been pressed since the last check
|
||||
*/
|
||||
bool kbd_break() {
|
||||
bool result = break_pressed;
|
||||
break_pressed = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the matrix keyboard
|
||||
*
|
||||
*/
|
||||
short kbd_sc_init() {
|
||||
// Initialize the keyboard buffers
|
||||
rb_word_init(&scan_code_buffer);
|
||||
rb_word_init(&char_buffer);
|
||||
|
||||
// Initialize the state of the keyboard
|
||||
kbd_state = kbd_state_default;
|
||||
modifiers = 0;
|
||||
break_pressed = false;
|
||||
|
||||
// Register and enable the PS/2 interrupt handler
|
||||
// int_register(INT_KBD_PS2, kbd_handle_irq);
|
||||
// int_enable(INT_KBD_PS2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
49
src/dev/kbd_f256jr.h
Normal file
49
src/dev/kbd_f256jr.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file kbd_f256jr.h
|
||||
* @author your name (you@domain.com)
|
||||
* @brief Driver for the F256jr PS/2 keyboard
|
||||
* @version 0.1
|
||||
* @date 2024-06-17
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __kbd_f256jr_h__
|
||||
#define __kbd_f256jr_h__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "sys_macros.h"
|
||||
|
||||
/**
|
||||
* @brief Handle an IRQ to query the keyboard
|
||||
*
|
||||
*/
|
||||
extern void kbd_handle_irq();
|
||||
|
||||
/*
|
||||
* Try to retrieve the next scancode from the keyboard.
|
||||
*
|
||||
* Returns:
|
||||
* The next scancode to be processed, 0 if nothing.
|
||||
*/
|
||||
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();
|
||||
|
||||
/*
|
||||
* Initialize the matrix keyboard
|
||||
*
|
||||
*/
|
||||
extern short kbd_sc_init();
|
||||
|
||||
#endif
|
|
@ -19,7 +19,6 @@
|
|||
#include "ring_buffer.h"
|
||||
#include "dev/kbd_f256k.h"
|
||||
#include "F256/via_f256.h"
|
||||
#include "uart.h"
|
||||
#include "gabe_reg.h"
|
||||
#include "simpleio.h"
|
||||
#include "vicky_general.h"
|
||||
|
@ -77,172 +76,6 @@ 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
|
||||
|
@ -252,20 +85,9 @@ 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 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
|
||||
*
|
||||
|
@ -423,147 +245,6 @@ 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.
|
||||
|
@ -579,53 +260,11 @@ bool kbd_break() {
|
|||
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
|
||||
*
|
||||
*/
|
||||
short kbd_init() {
|
||||
short kbd_sc_init() {
|
||||
// Initialize VIA0 -- we'll just read from PB7
|
||||
via0->ddra = 0x00;
|
||||
via0->ddrb = 0x00;
|
||||
|
@ -652,9 +291,6 @@ 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);
|
||||
|
||||
int_register(INT_VIA0, kbd_handle_irq);
|
||||
|
||||
via0->acr = 0x40; // Timer #0 in free running mode
|
||||
|
|
|
@ -40,41 +40,10 @@ extern unsigned short kbd_get_scancode();
|
|||
*/
|
||||
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
|
||||
*
|
||||
*/
|
||||
extern short kbd_init();
|
||||
extern short kbd_sc_init();
|
||||
|
||||
#endif
|
|
@ -35,7 +35,7 @@
|
|||
#include "dev/txt_evid.h"
|
||||
#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2
|
||||
#include "dev/txt_f256.h"
|
||||
#include "dev/kbd_f256k.h"
|
||||
#include "dev/kbd_f256.h"
|
||||
#include "dev/sdc_f256.h"
|
||||
#endif
|
||||
|
||||
|
@ -400,13 +400,7 @@ void read_sample_file(const char * path) {
|
|||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
short result;
|
||||
short i;
|
||||
char message[256];
|
||||
|
||||
initialize();
|
||||
|
||||
void test_sdc() {
|
||||
print_directory();
|
||||
|
||||
printf("\nfsys_rename(\"/sd0/hello.txt\", \"/sd0/renamed.txt\")");
|
||||
|
@ -423,6 +417,40 @@ int main(int argc, char * argv[]) {
|
|||
|
||||
read_sample_file("/sd0/test.txt");
|
||||
read_sample_file("/sd0/hello.txt");
|
||||
}
|
||||
|
||||
void test_kbd_sc() {
|
||||
printf("> ");
|
||||
do {
|
||||
unsigned short scancode = kbd_get_scancode();
|
||||
if (scancode != 0) {
|
||||
printf("%04X ", scancode);
|
||||
}
|
||||
} while (!kbd_break());
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
void test_kbd() {
|
||||
printf("> ");
|
||||
do {
|
||||
kbd_handle_irq();
|
||||
char c = kbd_getc();
|
||||
if (c != 0) {
|
||||
txt_put(0, c);
|
||||
}
|
||||
} while (!kbd_break());
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
short result;
|
||||
short i;
|
||||
char message[256];
|
||||
|
||||
initialize();
|
||||
kbd_init();
|
||||
|
||||
test_kbd();
|
||||
|
||||
// Attempt to start up the user code
|
||||
// log(LOG_INFO, "Looking for user startup code:");
|
||||
|
|
Loading…
Reference in a new issue