mirror of
https://github.com/clockworkpi/PicoCalc.git
synced 2025-12-12 18:28:53 +01:00
1079 lines
44 KiB
C
1079 lines
44 KiB
C
/*
|
|
* Keyboard.c
|
|
*
|
|
* Created on: 20 Apr 2019
|
|
* Author: Peter
|
|
*/
|
|
|
|
/***************************************************************************************************************************
|
|
MMBasic
|
|
|
|
keyboard.c
|
|
|
|
Does all the hard work in getting data from the PS2 keyboard
|
|
|
|
Copyright 2011 - 2018 Geoff Graham. All Rights Reserved.
|
|
|
|
This file and modified versions of this file are supplied to specific individuals or organisations under the following
|
|
provisions:
|
|
|
|
- This file, or any files that comprise the MMBasic source (modified or not), may not be distributed or copied to any other
|
|
person or organisation without written permission.
|
|
|
|
- Object files (.o and .hex files) generated using this file (modified or not) may not be distributed or copied to any other
|
|
person or organisation without written permission.
|
|
|
|
- This file is provided in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
****************************************************************************************************************************
|
|
|
|
This routine is based on a technique and code presented by Lucio Di Jasio in his excellent book
|
|
"Programming 32-bit Microcontrollers in C - Exploring the PIC32".
|
|
|
|
Thanks to Muller Fabrice (France), Alberto Leibovich (Argentina) and the other contributors who provided the code for
|
|
the non US keyboard layouts
|
|
|
|
****************************************************************************************************************************/
|
|
|
|
#include "MMBasic_Includes.h"
|
|
#include "Hardware_Includes.h"
|
|
void setLEDs(int num, int caps, int scroll);
|
|
bool sendCommand(int cmd, int clock, int data);
|
|
volatile char CapsLock;
|
|
volatile char NumLock;
|
|
volatile int setleds = 0;
|
|
// PS2 KBD state machine and buffer
|
|
static volatile int PS2State;
|
|
unsigned char KBDBuf;
|
|
static int KCount, KParity;
|
|
extern volatile int ConsoleRxBufHead;
|
|
extern volatile int ConsoleRxBufTail;
|
|
int justset = 0;
|
|
// extern char ConsoleRxBuf[];
|
|
|
|
volatile int KeyDownRegister;
|
|
volatile int KeyDownCode;
|
|
volatile int PS2code=0;
|
|
volatile bool PS2int=false;
|
|
// key codes that must be tracked for up/down state
|
|
#define CTRL 0x14 // left and right generate the same code
|
|
#define L_SHFT 0x12
|
|
#define R_SHFT 0x59
|
|
#define CAPS 0x58
|
|
#define NUML 0x77
|
|
static char LShift = 0;
|
|
static char RShift = 0;
|
|
static char PS2Ctrl = 0;
|
|
static char AltGrDown = 0;
|
|
static char KeyUpCode = false;
|
|
static char KeyE0 = false;
|
|
|
|
// this is a map of the keycode characters and the character to be returned for the keycode
|
|
const char keyCodes[8][128] =
|
|
// US Layout
|
|
{
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '`', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'q', '1', 0, // 16-23 10-07
|
|
0, 0, 'z', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '6', 0, // 48-56 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', '/', 'l', ';', 'p', '-', 0, // 72-79 48-4F
|
|
0, 0, '\'', 0, '[', '=', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, ']', 0, 0x5c, 0, 0, // 88-95 58-5F
|
|
0, 0, 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// FR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'a', '&', 0, // 16-23 10-07
|
|
0, 0, 'w', 's', 'q', 'z', 0, 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '\'', '"', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '(', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '-', 0, // 48-56 30-37
|
|
0, 0, ',', 'j', 'u', 0, '_', 0, // 56-63 38-3F
|
|
0, ';', 'k', 'i', 'o', 0, 0, 0, // 64-71 40-47
|
|
0, ':', '!', 'l', 'm', 'p', ')', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, '^', '=', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '$', 0, '*', 0, 0, // 88-95 58-5F
|
|
0, '<', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// GR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '^', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'q', '1', 0, // 16-23 10-07
|
|
0, 0, 'y', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-47 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'z', '6', 0, // 48-55 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', '-', 'l', 0, 'p', 0, 0, // 72-79 48-4F
|
|
0, 0, 0, 0, 0, '\'', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '+', 0, '#', 0, 0, // 88-95 58-5F
|
|
0, '<', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// IT Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0x5c, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'q', '1', 0, // 16-23 10-07
|
|
0, 0, 'z', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '6', 0, // 48-56 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', '-', 'l', 0, 'p', '\'', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, 0, 0, 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '+', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '<', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// BE Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'a', '&', 0, // 16-23 10-07
|
|
0, 0, 'w', 's', 'q', 'z', 0, 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '\'', '"', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '(', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', 0, 0, // 48-56 30-37
|
|
0, 0, ',', 'j', 'u', 0, '!', 0, // 56-63 38-3F
|
|
0, ';', 'k', 'i', 'o', 0, 0, 0, // 64-71 40-47
|
|
0, ':', '=', 'l', 'm', 'p', ')', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, '^', '-', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '$', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '<', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// UK Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '`', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0x5C, CTRL, 'q', '1', 0, // 16-23 10-07
|
|
0, 0, 'z', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '6', 0, // 48-56 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', '/', 'l', ';', 'p', '-', 0, // 72-79 48-4F
|
|
0, 0, '\'', 0, '[', '=', 0x5C, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, ']', '#', '#', 0, 0, // 88-95 58-5F
|
|
0, 0x5C, 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// ES Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0x5c, 0, // 08-15 08-0F 0x5C is backslash
|
|
0, ALT, L_SHFT, 0, CTRL, 'q', '1', 0, // 16-23 10-07
|
|
0, 0, 'z', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-47 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '6', 0, // 48-55 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', '-', 'l', 0, 'p', '\'', 0, // 72-79 48-4F
|
|
0, 0, '\'', 0, 0x60, 0, 0, 0, // 80-87 50-57 0x60 a single quote
|
|
CAPS, R_SHFT, ENTER, '+', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '<', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// BR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '\'', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'q', '1', 0, // 16-23 10-17
|
|
0, 0, 'z', 's', 'a', 'w', '2', 0, // 24-31 18-1F
|
|
0, 'c', 'x', 'd', 'e', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'v', 'f', 't', 'r', '5', 0, // 40-48 28-2F
|
|
0, 'n', 'b', 'h', 'g', 'y', '6', 0, // 48-56 30-37
|
|
0, 0, 'm', 'j', 'u', '7', '8', 0, // 56-63 38-3F
|
|
0, ',', 'k', 'i', 'o', '0', '9', 0, // 64-71 40-47
|
|
0, '.', ';', 'l', 'c', 'p', '-', 0, // 72-79 48-4F
|
|
0, '/', '~', 0, 0, '=', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '[', 0, ']', 0, 0, // 88-95 58-5F
|
|
0, '\\', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', '.', 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
}};
|
|
|
|
// this map is with the shift key pressed
|
|
const char keySCodes[8][128] =
|
|
// US Layout
|
|
{
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '~', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'Q', '!', 0, // 16-23 10-17
|
|
0, 0, 'Z', 'S', 'A', 'W', '@', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', '#', 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '&', '*', 0, // 56-63 38-3F
|
|
0, '<', 'K', 'I', 'O', ')', '(', 0, // 64-71 40-47
|
|
0, '>', '?', 'L', ':', 'P', '_', 0, // 72-79 48-4F
|
|
0, 0, '\"', 0, '{', '+', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '}', 0, '|', 0, 0, // 88-95 58-5F
|
|
0, 0, 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// FR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'A', '1', 0, // 16-23 10-17
|
|
0, 0, 'W', 'S', 'Q', 'Z', '2', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '5', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '6', 0, // 48-55 30-37
|
|
0, 0, '?', 'J', 'U', '7', '8', 0, // 56-63 38-3F
|
|
0, '.', 'K', 'I', 'O', '0', '9', 0, // 64-71 40-47
|
|
0, '/', 0, 'L', 'M', 'P', 0, 0, // 72-79 48-4F
|
|
0, 0, '%', 0, 0, '+', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, 0, 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '>', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// GR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'Q', '!', 0, // 16-23 10-07
|
|
0, 0, 'Y', 'S', 'A', 'W', '\"', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', 0, 0, // 32-39 20-27
|
|
0, '\'', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Z', '&', 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '/', '(', 0, // 56-63 38-3F
|
|
0, ';', 'K', 'I', 'O', '=', ')', 0, // 64-71 40-47
|
|
0, ':', '_', 'L', 0, 'P', '?', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, 0, 0, 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '*', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '>', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// IT Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '|', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'Q', '!', 0, // 16-23 10-17
|
|
0, 0, 'Z', 'S', 'A', 'W', '\"', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', 0, 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '&', 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '/', '(', 0, // 56-63 38-3F
|
|
0, ';', 'K', 'I', 'O', '=', ')', 0, // 64-71 40-47
|
|
0, ':', '_', 'L', 0, 'P', '?', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, 0, '^', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '*', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '>', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// BE Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0, 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, 0, CTRL, 'A', '1', 0, // 16-23 10-17
|
|
0, 0, 'W', 'S', 'Q', 'Z', '2', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '4', '3', 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '5', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '6', 0, // 48-55 30-37
|
|
0, 0, '?', 'J', 'U', '7', '8', 0, // 56-63 38-3F
|
|
0, '.', 'K', 'I', 'O', '0', '9', 0, // 64-71 40-47
|
|
0, '/', '+', 'L', 'M', 'P', 0, 0, // 72-79 48-4F
|
|
0, 0, '%', 0, 0, '_', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '*', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '>', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// UK Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '~', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, '|', CTRL, 'Q', '!', 0, // 16-23 10-17
|
|
0, 0, 'Z', 'S', 'A', 'W', '\"', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', '#', 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '&', '*', 0, // 56-63 38-3F
|
|
0, '<', 'K', 'I', 'O', ')', '(', 0, // 64-71 40-47
|
|
0, '>', '?', 'L', ':', 'P', '_', 0, // 72-79 48-4F
|
|
0, 0, '@', 0, '{', '+', '|', 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '}', '~', '~', 0, 0, // 88-95 58-5F
|
|
0, '|', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// ES Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, 0x5C, 0, // 08-15 08-0F 0x5C is backslash
|
|
0, ALT, L_SHFT, 0, CTRL, 'Q', '!', 0, // 16-23 10-17
|
|
0, 0, 'Z', 'S', 'A', 'W', '\"', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', 0, 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', '&', 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '/', '(', 0, // 56-63 38-3F
|
|
0, ';', 'K', 'I', 'O', '=', ')', 0, // 64-71 40-47
|
|
0, ':', '_', 'L', 0, 'P', '?', 0, // 72-79 48-4F
|
|
0, 0, 0, 0, '^', 0, 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '*', 0, 0, 0, 0, // 88-95 58-5F
|
|
0, '>', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', 0, 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
},
|
|
// BR Layout
|
|
{
|
|
// Base 10 Hex
|
|
0, F9, 0, F5, F3, F1, F2, F12, // 00-07 00-07
|
|
0, F10, F8, F6, F4, TAB, '\"', 0, // 08-15 08-0F
|
|
0, ALT, L_SHFT, CTRL, 'Q', 0, '!', 0, // 16-23 10-17
|
|
0, 0, 'Z', 'S', 'A', 'W', '@', 0, // 24-31 18-1F
|
|
0, 'C', 'X', 'D', 'E', '$', '#', 0, // 32-39 20-27
|
|
0, ' ', 'V', 'F', 'T', 'R', '%', 0, // 40-47 28-2F
|
|
0, 'N', 'B', 'H', 'G', 'Y', 0, 0, // 48-55 30-37
|
|
0, 0, 'M', 'J', 'U', '&', '*', 0, // 56-63 38-3F
|
|
0, '<', 'K', 'I', 'O', ')', '(', 0, // 64-71 40-47
|
|
0, '>', ':', 'L', 'C', 'P', '_', 0, // 72-79 48-4F
|
|
0, '?', '^', 0, 0, '+', 0, 0, // 80-87 50-57
|
|
CAPS, R_SHFT, ENTER, '{', 0, '}', 0, 0, // 88-95 58-5F
|
|
0, '|', 0, 0, 0, 0, BKSP, 0, // 96-103 60-67
|
|
0, '1', 0, '4', '7', '.', 0, 0, // 104-111 68-6F
|
|
'0', '.', '2', '5', '6', '8', ESC, NUML, // 112-119 70-77
|
|
F11, '+', '3', '-', '*', '9', 0, 0 // 120-127 78-7F
|
|
}};
|
|
|
|
// this map is for when the keycode preceeded by 0xe0
|
|
const char keyE0Codes[56] =
|
|
// General Layout on all Keyboard for the Keypad
|
|
{
|
|
// Base 10
|
|
0, END, 0, LEFT, HOME, 0, 0, 0, // 104-111
|
|
INSERT, DEL, DOWN, 0, RIGHT, UP, ESC, NUML, // 112-119
|
|
F11, '+', PDOWN, '-', '*', PUP, SLOCK, 0, // 120-127
|
|
};
|
|
|
|
const char keyE0Codes_ES[56] =
|
|
// Layout for spanish Keyboard for the Keypad
|
|
{
|
|
// Base 10
|
|
0, END, 0, LEFT, HOME, 0, 0, 0, // 104-111
|
|
INSERT, DEL, DOWN, PUP, RIGHT, UP, ESC, NUML, // 112-119
|
|
F11, 0, PDOWN, 0, 0, 0, SLOCK, 0, // 120-127
|
|
};
|
|
|
|
void KBDIntEnable(int status)
|
|
{
|
|
PinSetBit(Option.KEYBOARD_CLOCK, TRISSET); // if tris = 1 then it is an input
|
|
PinSetBit(Option.KEYBOARD_DATA, TRISSET); // if tris = 1 then it is an input
|
|
PinSetBit(Option.KEYBOARD_CLOCK, CNPUSET); // if tris = 1 then it is an input
|
|
PinSetBit(Option.KEYBOARD_DATA, CNPUSET); // if tris = 1 then it is an input
|
|
if (status)
|
|
{
|
|
if (!CallBackEnabled)
|
|
{
|
|
CallBackEnabled = 32;
|
|
gpio_set_irq_enabled_with_callback(PinDef[Option.KEYBOARD_CLOCK].GPno, GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
|
|
}
|
|
else
|
|
{
|
|
CallBackEnabled |= 32;
|
|
gpio_set_irq_enabled(PinDef[Option.KEYBOARD_CLOCK].GPno, GPIO_IRQ_EDGE_FALL, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CallBackEnabled == 32)
|
|
gpio_set_irq_enabled_with_callback(PinDef[Option.KEYBOARD_CLOCK].GPno, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false, &gpio_callback);
|
|
else
|
|
gpio_set_irq_enabled(PinDef[Option.KEYBOARD_CLOCK].GPno, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false);
|
|
CallBackEnabled &= (~32);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************************************
|
|
initKeyboard
|
|
Initialise the keyboard routine.
|
|
****************************************************************************************************/
|
|
void initKeyboard(void)
|
|
{
|
|
// GPIO_InitTypeDef GPIO_InitDef;
|
|
|
|
if (Option.KeyboardConfig == NO_KEYBOARD || Option.KeyboardConfig==CONFIG_I2C) return;
|
|
KBDIntEnable(0); // disable interrupt in case called from within CNInterrupt()
|
|
|
|
// enable pullups on the clock and data lines.
|
|
// sendCommand(0xFF);
|
|
// HAL_Delay(100);
|
|
// setup Change Notification interrupt
|
|
KBDIntEnable(1); // enable interrupt
|
|
PS2State = PS2START;
|
|
CapsLock = Option.capslock;
|
|
NumLock = Option.numlock;
|
|
uSec(100000);
|
|
setLEDs(CapsLock, NumLock, 0);
|
|
}
|
|
|
|
/***************************************************************************************************
|
|
sendCommand - Send a command to to keyboard.
|
|
****************************************************************************************************/
|
|
bool sendCommand(int cmd, int clock, int data)
|
|
{
|
|
int i, j;
|
|
|
|
// calculate the parity and add to the command as the 9th bit
|
|
for (j = i = 0; i < 8; i++) j += ((cmd >> i) & 1);
|
|
cmd = (cmd & 0xff) | (((j + 1) & 1) << 8);
|
|
InkeyTimer = 0;
|
|
/* while (!PinRead(clock)) //wait for clock high
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
}*/
|
|
PinSetBit(clock, TRISCLR);
|
|
PinSetBit(clock, LATCLR);
|
|
uSec(250);
|
|
PinSetBit(data, TRISCLR);
|
|
PinSetBit(data, LATCLR);
|
|
uSec(2);
|
|
PinSetBit(clock, TRISSET);
|
|
uSec(2);
|
|
while (PinRead(clock))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
}
|
|
|
|
// send each bit including parity
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
if (cmd & 1)
|
|
{
|
|
PinSetBit(data, LATSET);
|
|
}
|
|
else
|
|
{
|
|
PinSetBit(data, LATCLR);
|
|
}
|
|
while (!PinRead(clock))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
}
|
|
while (PinRead(clock))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
}
|
|
cmd >>= 1;
|
|
}
|
|
|
|
// PinSetBit(clock, TRISSET);
|
|
PinSetBit(data, TRISSET);
|
|
|
|
while (PinRead(data))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
} // wait for the keyboard to pull data low (ACK)
|
|
while (PinRead(clock))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
} // wait for the clock to go low
|
|
while (!(PinRead(clock)) || !(PinRead(data)))
|
|
if (InkeyTimer >= 500)
|
|
{ // wait for the keyboard to pull the clock low
|
|
return false; // wait for the keyboard to pull the clock low
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// set the keyboard LEDs
|
|
void setLEDs(int caps, int num, int scroll)
|
|
{
|
|
setleds = 0;
|
|
KBDIntEnable(0); // disable interrupt while we play
|
|
PS2State = PS2START;
|
|
sendCommand(0xED, Option.KEYBOARD_CLOCK, Option.KEYBOARD_DATA); // Set/Reset Status Indicators Command
|
|
uSec(50000);
|
|
sendCommand(((caps & 1) << 2) | ((num & 1) << 1) | (scroll & 1), Option.KEYBOARD_CLOCK, Option.KEYBOARD_DATA); // set the various LEDs
|
|
uSec(50000);
|
|
sendCommand(0xF3, Option.KEYBOARD_CLOCK, Option.KEYBOARD_DATA); // Set/Reset Status Indicators Command
|
|
uSec(50000);
|
|
sendCommand(Option.repeat, Option.KEYBOARD_CLOCK, Option.KEYBOARD_DATA);
|
|
KBDIntEnable(1); // re enable interrupt
|
|
justset = 1;
|
|
}
|
|
|
|
void __not_in_flash_func(CheckKeyboard)(void)
|
|
{
|
|
if (setleds)
|
|
{
|
|
setLEDs(CapsLock, NumLock, 0);
|
|
}
|
|
}
|
|
void processcode(unsigned char Code){
|
|
unsigned char c = 0;
|
|
// unsigned int dly;
|
|
if(!(Code==0xe0 || Code==0xf0 || (Code==0x12 && KeyE0) || (Code==0x12 && KeyUpCode)) && Code){
|
|
PS2int=true;
|
|
PS2code=Code;
|
|
}
|
|
|
|
if(KeyUpCode)PS2code|=0xf000;
|
|
if(KeyE0)PS2code|=0xe000;
|
|
if(KeyE0 && KeyUpCode)PS2code|=0xe0f000;
|
|
if (Code == 0xaa)
|
|
{ // self test code (a keyboard must have just been plugged in)
|
|
CapsLock = 0;
|
|
NumLock = 1;
|
|
} // so initialise it
|
|
else if (Code == 0xf0) // a key has been released
|
|
KeyUpCode = true;
|
|
else if (Code == 0xe0) // extended keycode prefix
|
|
KeyE0 = true;
|
|
else
|
|
{
|
|
// Process a scan code from the keyboard into an ASCII character.
|
|
// It then inserts the char into the keyboard queue.
|
|
|
|
// for the US keyboard and the right Alt key we need to make it the same as the left Alt key
|
|
if (Option.KeyboardConfig == CONFIG_US && KeyE0 && Code == 0x11)
|
|
KeyE0 = false;
|
|
|
|
// if a key has been released we are only interested in resetting state keys
|
|
if (KeyUpCode)
|
|
{
|
|
if (Code == L_SHFT)
|
|
LShift = 0; // left shift button is released
|
|
else if (Code == R_SHFT)
|
|
RShift = 0; // right shift button is released
|
|
else if (Code == CTRL)
|
|
PS2Ctrl = 0; // left control button is released
|
|
else if (KeyE0 && Code == 0x11)
|
|
AltGrDown = 0; // release the AltGr key on non US keyboards
|
|
else if (Code == KeyDownCode)
|
|
KeyDownRegister = 0; // normal char so record that it is no longer depressed
|
|
goto SkipOut;
|
|
}
|
|
|
|
// we are only here if the key has been pressed (NOT released)
|
|
if (Code == L_SHFT)
|
|
{
|
|
LShift = 1;
|
|
goto SkipOut;
|
|
} // left shift button is pressed
|
|
if (Code == R_SHFT)
|
|
{
|
|
RShift = 1;
|
|
goto SkipOut;
|
|
} // right shift button is pressed
|
|
if (Code == CTRL)
|
|
{
|
|
PS2Ctrl = 1;
|
|
goto SkipOut;
|
|
} // left control button is pressed
|
|
if (Code == CAPS)
|
|
{
|
|
CapsLock = !CapsLock;
|
|
setleds = 1;
|
|
// setLEDs(CapsLock, NumLock, 3);
|
|
goto SkipOut;
|
|
}
|
|
if (Code == NUML)
|
|
{ // caps or num lock pressed
|
|
NumLock = !NumLock;
|
|
setleds = 1;
|
|
// setLEDs(CapsLock, NumLock, 7);
|
|
goto SkipOut;
|
|
}
|
|
if (KeyE0 && Code == 0x11)
|
|
{
|
|
AltGrDown = 1;
|
|
goto SkipOut;
|
|
} // AltGr key pressed on non US Keyboard
|
|
|
|
// now get the character into c. Why, oh why, are scan codes so random?
|
|
if (!KeyE0 && Code == 0x83)
|
|
c = 0x97; // a special case, function key F7
|
|
else if (KeyE0 && Code == 0x4A)
|
|
c = '/'; // another special case, this time the keypad forward slash
|
|
else if (KeyE0 && Code == 0x5A)
|
|
c = NUM_ENT; // yet another special case, this time the keypad enter key
|
|
else if ((KeyE0 || !NumLock) && Code >= 104 && Code < 0x80 && !AltGrDown)
|
|
{ // a keycode from the numeric keypad
|
|
LShift = 0; // when num lock LED is on codes are preceeded by left shift
|
|
if (Option.KeyboardConfig == CONFIG_ES)
|
|
c = keyE0Codes_ES[Code - 104];
|
|
else
|
|
c = keyE0Codes[Code - 104];
|
|
if (PS2Ctrl)
|
|
{ // special for PB
|
|
if (c == UP)
|
|
c = PUP; // CTRL-UP to page up
|
|
if (c == DOWN)
|
|
c = PDOWN; // CTRL-DOWN to page down
|
|
if (c == LEFT)
|
|
c = HOME; // CTRL-LEFT to home
|
|
if (c == RIGHT)
|
|
c = END; // CTRL-RIGHT to end
|
|
}
|
|
}
|
|
else if ((Code >= 0x15 && Code < 0x62) && AltGrDown != 0) // a keycode preceeded by Alt-Gr
|
|
switch (Option.KeyboardConfig)
|
|
{ // an international keycode pressed with
|
|
case CONFIG_US: // the AltGr key
|
|
break; // no code for US keyboard
|
|
case CONFIG_FR: // French Keyboard
|
|
switch (Code)
|
|
{
|
|
case 0x45:
|
|
c = 0x40; // @
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x25:
|
|
c = 0x7b; // {
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x2e:
|
|
c = 0x5b; // [
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x55:
|
|
c = 0x7d; // }
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x4e:
|
|
c = 0x5d; // ]
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x3e:
|
|
c = 0x5c; // '\'
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x1e:
|
|
c = 0x7e; // ~
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x36:
|
|
c = 0x7c; // |
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x26:
|
|
c = 0x23; // #
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case CONFIG_GR: // German Keyboard
|
|
switch (Code)
|
|
{
|
|
case 0x15:
|
|
c = 0x40; // @
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x3d:
|
|
c = 0x7b; // {
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x3e:
|
|
c = 0x5b; // [
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x45:
|
|
c = 0x7d; // }
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x46:
|
|
c = 0x5d; // ]
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x4e:
|
|
c = 0x5c; // '\'
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x5b:
|
|
c = 0x7e; // ~
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x61:
|
|
c = 0x7c; // |
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case CONFIG_IT: // Italian Keyboard
|
|
switch (Code)
|
|
{
|
|
case 0x4C:
|
|
c = 0x40; // @
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x54:
|
|
c = 0x5b; // [
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x5b:
|
|
c = 0x5d; // ]
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x52:
|
|
c = 0x23; // #
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case CONFIG_BE: // Belgian Keyboard
|
|
switch (Code)
|
|
{
|
|
case 0x1e:
|
|
c = 0x40; // @
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x46:
|
|
c = 0x7b; // {
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x54:
|
|
c = 0x5b; // [
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x45:
|
|
c = 0x7d; // }
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x5b:
|
|
c = 0x5d; // ]
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x1a:
|
|
c = 0x5c; // '\'
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x4a:
|
|
c = 0x7e; // ~
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x16:
|
|
c = 0x7c; // |
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x26:
|
|
c = 0x23; // #
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case CONFIG_ES: // Spanish Keyboard
|
|
switch (Code)
|
|
{
|
|
case 0x1E:
|
|
c = 0x40; // @
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x54:
|
|
c = 0x5b; // [
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x5b:
|
|
c = 0x5d; // ]
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x26:
|
|
c = 0x23; // #
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x52:
|
|
c = 0x7b; // {
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x5d:
|
|
c = 0x7d; // }
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x16:
|
|
c = 0x7c; // |
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x0e:
|
|
c = 0x5c; // '\'
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x25:
|
|
c = 0x7e; // ~
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case CONFIG_BR: // Brazilian Keyboard (TO DO)
|
|
switch (Code)
|
|
{
|
|
case 0x1D:
|
|
c = '?'; // ?
|
|
AltGrDown = 0;
|
|
break;
|
|
case 0x14:
|
|
c = '/'; // /
|
|
AltGrDown = 0;
|
|
break;
|
|
default:
|
|
c = 0; // invalid code
|
|
AltGrDown = 0;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
switch (Option.KeyboardConfig)
|
|
{
|
|
case CONFIG_US:
|
|
if (LShift || RShift)
|
|
c = keySCodes[0][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[0][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_FR:
|
|
if (LShift || RShift)
|
|
c = keySCodes[1][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[1][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_GR:
|
|
if (LShift || RShift)
|
|
c = keySCodes[2][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[2][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_IT:
|
|
if (LShift || RShift)
|
|
c = keySCodes[3][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[3][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_BE:
|
|
if (LShift || RShift)
|
|
c = keySCodes[4][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[4][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_UK:
|
|
if (LShift || RShift)
|
|
c = keySCodes[5][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[5][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_ES:
|
|
if (LShift || RShift)
|
|
c = keySCodes[6][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[6][Code % 128]; // just a keycode
|
|
break;
|
|
case CONFIG_BR:
|
|
if (LShift || RShift)
|
|
c = keySCodes[7][Code % 128]; // a keycode preceeded by a shift
|
|
else
|
|
c = keyCodes[7][Code % 128]; // just a keycode
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!c)
|
|
goto SkipOut;
|
|
|
|
if (c <= 0x7F)
|
|
{ // a normal character
|
|
if (CapsLock && c >= 'a' && c <= 'z')
|
|
c -= 32; // adj for caps lock
|
|
if (PS2Ctrl)
|
|
c &= 0x1F; // adj for control
|
|
}
|
|
else
|
|
{ // must be a function key or similar
|
|
if (LShift || RShift)
|
|
c |= 0b00100000;
|
|
// NOTE: Special for PB, CTRL-UP to page up, CTRL-DOWN to page down, CTRL-LEFT to home, CTRL-RIGHT to end
|
|
if (PS2Ctrl && !(c == PUP || c == PDOWN || c == HOME || c == END))
|
|
c |= 0b01000000;
|
|
}
|
|
|
|
if (BreakKey && c == BreakKey)
|
|
{ // if the user wants to stop the progran
|
|
MMAbort = true; // set the flag for the interpreter to see
|
|
ConsoleRxBufHead = ConsoleRxBufTail; // empty the buffer
|
|
// break;
|
|
}
|
|
else
|
|
{
|
|
if (!(justset && c == '3'))
|
|
{
|
|
Timer3=0;
|
|
ConsoleRxBuf[ConsoleRxBufHead] = c; // store the byte in the ring buffer
|
|
if (ConsoleRxBuf[ConsoleRxBufHead] == keyselect && KeyInterrupt != NULL)
|
|
{
|
|
Keycomplete = true;
|
|
}
|
|
else
|
|
{
|
|
ConsoleRxBufHead = (ConsoleRxBufHead + 1) % CONSOLE_RX_BUF_SIZE; // advance the head of the queue
|
|
if (ConsoleRxBufHead == ConsoleRxBufTail)
|
|
{ // if the buffer has overflowed
|
|
ConsoleRxBufTail = (ConsoleRxBufTail + 1) % CONSOLE_RX_BUF_SIZE; // throw away the oldest char
|
|
}
|
|
}
|
|
}
|
|
else
|
|
justset = 0;
|
|
}
|
|
|
|
SkipOut:
|
|
// end lump of self contained code
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
KeyUpCode = false;
|
|
KeyE0 = false;
|
|
}
|
|
}
|
|
/***************************************************************************************************
|
|
change notification interrupt service routine
|
|
****************************************************************************************************/
|
|
void __not_in_flash_func(CNInterrupt)(uint64_t dd)
|
|
{
|
|
static unsigned char Code = 0;
|
|
int d = dd & (1<<PinDef[Option.KEYBOARD_DATA].GPno);
|
|
|
|
// Make sure it was a falling edge
|
|
if (!(dd & (1<<PinDef[Option.KEYBOARD_CLOCK].GPno)))
|
|
{
|
|
if(!Timer3)PS2State=PS2START;
|
|
switch (PS2State)
|
|
{
|
|
default:
|
|
case PS2ERROR: // this can happen if a timing or parity error occurs
|
|
// ClickTimer = 50;
|
|
LShift = 0; // reset the CTRL, SHIFT and other keys
|
|
RShift = 0;
|
|
PS2Ctrl = 0;
|
|
AltGrDown = 0;
|
|
KeyUpCode = false;
|
|
KeyE0 = false;
|
|
// fall through to PS2START
|
|
|
|
case PS2START:
|
|
if (!d)
|
|
{ // PS2DAT == 0
|
|
KCount = 8; // init bit counter
|
|
KParity = 0; // init parity check
|
|
Code = 0;
|
|
PS2State = PS2BIT;
|
|
Timer3=5;
|
|
}
|
|
break;
|
|
|
|
case PS2BIT:
|
|
Code >>= 1; // shift in data bit
|
|
if (d)
|
|
Code |= 0x80; // PS2DAT == 1
|
|
KParity ^= Code; // calculate parity
|
|
if (--KCount <= 0)
|
|
PS2State = PS2PARITY; // all bit read
|
|
break;
|
|
|
|
case PS2PARITY:
|
|
if (d)
|
|
KParity ^= 0x80; // PS2DAT == 1
|
|
if (KParity & 0x80) // parity odd, continue
|
|
PS2State = PS2STOP;
|
|
else {
|
|
PS2State = PS2ERROR;
|
|
putConsole('q',1);
|
|
}
|
|
break;
|
|
|
|
case PS2STOP:
|
|
if (d)
|
|
{ // PS2DAT == 1
|
|
processcode(Code);
|
|
Code = 0;
|
|
}
|
|
PS2State = PS2START;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|