2616 lines
119 KiB
C
2616 lines
119 KiB
C
/*
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
|
* running old operating systems and software designed for IBM
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
* system designs based on the PCI bus.
|
|
*
|
|
* This file is part of the 86Box distribution.
|
|
*
|
|
* Intel 8042 (AT keyboard controller) emulation.
|
|
*
|
|
*
|
|
*
|
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
|
* Miran Grca, <mgrca8@gmail.com>
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
|
* EngiNerd <webmaster.crrc@yahoo.it>
|
|
*
|
|
* Copyright 2008-2020 Sarah Walker.
|
|
* Copyright 2016-2020 Miran Grca.
|
|
* Copyright 2017-2020 Fred N. van Kempen.
|
|
* Copyright 2020 EngiNerd.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#define HAVE_STDARG_H
|
|
#include <wchar.h>
|
|
#include <86box/86box.h>
|
|
#include "cpu.h"
|
|
#include <86box/timer.h>
|
|
#include <86box/io.h>
|
|
#include <86box/pic.h>
|
|
#include <86box/pit.h>
|
|
#include <86box/ppi.h>
|
|
#include <86box/mem.h>
|
|
#include <86box/device.h>
|
|
#include <86box/machine.h>
|
|
#include <86box/m_xt_xi8088.h>
|
|
#include <86box/m_at_t3100e.h>
|
|
#include <86box/fdd.h>
|
|
#include <86box/fdc.h>
|
|
#include <86box/sound.h>
|
|
#include <86box/snd_speaker.h>
|
|
#include <86box/video.h>
|
|
#include <86box/keyboard.h>
|
|
|
|
|
|
#define STAT_PARITY 0x80
|
|
#define STAT_RTIMEOUT 0x40
|
|
#define STAT_TTIMEOUT 0x20
|
|
#define STAT_MFULL 0x20
|
|
#define STAT_UNLOCKED 0x10
|
|
#define STAT_CD 0x08
|
|
#define STAT_SYSFLAG 0x04
|
|
#define STAT_IFULL 0x02
|
|
#define STAT_OFULL 0x01
|
|
|
|
#define RESET_DELAY_TIME (100 * 10) /* 600ms */
|
|
|
|
#define CCB_UNUSED 0x80
|
|
#define CCB_TRANSLATE 0x40
|
|
#define CCB_PCMODE 0x20
|
|
#define CCB_ENABLEKBD 0x10
|
|
#define CCB_IGNORELOCK 0x08
|
|
#define CCB_SYSTEM 0x04
|
|
#define CCB_ENABLEMINT 0x02
|
|
#define CCB_ENABLEKINT 0x01
|
|
|
|
#define CCB_MASK 0x68
|
|
#define MODE_MASK 0x6c
|
|
|
|
#define KBC_TYPE_ISA 0x00 /* AT ISA-based chips */
|
|
#define KBC_TYPE_PS2_NOREF 0x01 /* PS2 type, no refresh */
|
|
#define KBC_TYPE_PS2_1 0x02 /* PS2 on PS/2, type 1 */
|
|
#define KBC_TYPE_PS2_2 0x03 /* PS2 on PS/2, type 2 */
|
|
#define KBC_TYPE_MASK 0x03
|
|
|
|
#define KBC_VEN_GENERIC 0x00
|
|
#define KBC_VEN_AMI 0x04
|
|
#define KBC_VEN_IBM_MCA 0x08
|
|
#define KBC_VEN_QUADTEL 0x0c
|
|
#define KBC_VEN_TOSHIBA 0x10
|
|
#define KBC_VEN_XI8088 0x14
|
|
#define KBC_VEN_IBM_PS1 0x18
|
|
#define KBC_VEN_ACER 0x1c
|
|
#define KBC_VEN_INTEL_AMI 0x20
|
|
#define KBC_VEN_OLIVETTI 0x24
|
|
#define KBC_VEN_NCR 0x28
|
|
#define KBC_VEN_SAMSUNG 0x2c
|
|
#define KBC_VEN_MASK 0x3c
|
|
|
|
|
|
typedef struct {
|
|
uint8_t command, status, old_status, out, old_out, secr_phase,
|
|
mem_addr, input_port, output_port, old_output_port,
|
|
key_command, output_locked, ami_stat, want60,
|
|
wantirq, key_wantdata, ami_flags, first_write;
|
|
|
|
uint8_t mem[0x100];
|
|
|
|
int last_irq, old_last_irq,
|
|
reset_delay,
|
|
out_new, out_delayed;
|
|
|
|
uint32_t flags;
|
|
|
|
pc_timer_t pulse_cb;
|
|
|
|
uint8_t (*write60_ven)(void *p, uint8_t val);
|
|
uint8_t (*write64_ven)(void *p, uint8_t val);
|
|
|
|
pc_timer_t send_delay_timer;
|
|
} atkbd_t;
|
|
|
|
|
|
/* bit 0 = repeat, bit 1 = makes break code? */
|
|
uint8_t keyboard_set3_flags[512];
|
|
uint8_t keyboard_set3_all_repeat;
|
|
uint8_t keyboard_set3_all_break;
|
|
|
|
/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */
|
|
uint8_t keyboard_mode = 0x42;
|
|
|
|
|
|
static uint8_t key_ctrl_queue[16];
|
|
static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0;
|
|
static uint8_t key_queue[16];
|
|
static int key_queue_start = 0, key_queue_end = 0;
|
|
uint8_t mouse_queue[16];
|
|
int mouse_queue_start = 0, mouse_queue_end = 0;
|
|
static uint8_t kbd_last_scan_code;
|
|
static void (*mouse_write)(uint8_t val, void *priv) = NULL;
|
|
static void *mouse_p = NULL;
|
|
static uint8_t sc_or = 0;
|
|
static atkbd_t *SavedKbd = NULL; // FIXME: remove!!! --FvK
|
|
|
|
|
|
/* Non-translated to translated scan codes. */
|
|
static const uint8_t nont_to_t[256] = {
|
|
0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
|
|
0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
|
|
0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
|
|
0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
|
|
0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
|
|
0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
|
|
0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
|
|
0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
|
|
0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
|
|
0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
|
|
0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
|
|
0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
|
|
0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
|
|
0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
|
|
0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
|
|
0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
|
|
0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
|
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
|
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
|
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
|
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
|
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
|
};
|
|
|
|
#ifdef USE_SET1
|
|
static const scancode scancode_set1[512] = {
|
|
{ { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/
|
|
{ { 0x04,0},{ 0x84,0} }, { { 0x05,0},{ 0x85,0} }, { { 0x06,0},{ 0x86,0} }, { { 0x07,0},{ 0x87,0} }, /*004*/
|
|
{ { 0x08,0},{ 0x88,0} }, { { 0x09,0},{ 0x89,0} }, { { 0x0a,0},{ 0x8a,0} }, { { 0x0b,0},{ 0x8b,0} }, /*008*/
|
|
{ { 0x0c,0},{ 0x8c,0} }, { { 0x0d,0},{ 0x8d,0} }, { { 0x0e,0},{ 0x8e,0} }, { { 0x0f,0},{ 0x8f,0} }, /*00c*/
|
|
{ { 0x10,0},{ 0x90,0} }, { { 0x11,0},{ 0x91,0} }, { { 0x12,0},{ 0x92,0} }, { { 0x13,0},{ 0x93,0} }, /*010*/
|
|
{ { 0x14,0},{ 0x94,0} }, { { 0x15,0},{ 0x95,0} }, { { 0x16,0},{ 0x96,0} }, { { 0x17,0},{ 0x97,0} }, /*014*/
|
|
{ { 0x18,0},{ 0x98,0} }, { { 0x19,0},{ 0x99,0} }, { { 0x1a,0},{ 0x9a,0} }, { { 0x1b,0},{ 0x9b,0} }, /*018*/
|
|
{ { 0x1c,0},{ 0x9c,0} }, { { 0x1d,0},{ 0x9d,0} }, { { 0x1e,0},{ 0x9e,0} }, { { 0x1f,0},{ 0x9f,0} }, /*01c*/
|
|
{ { 0x20,0},{ 0xa0,0} }, { { 0x21,0},{ 0xa1,0} }, { { 0x22,0},{ 0xa2,0} }, { { 0x23,0},{ 0xa3,0} }, /*020*/
|
|
{ { 0x24,0},{ 0xa4,0} }, { { 0x25,0},{ 0xa5,0} }, { { 0x26,0},{ 0xa6,0} }, { { 0x27,0},{ 0xa7,0} }, /*024*/
|
|
{ { 0x28,0},{ 0xa8,0} }, { { 0x29,0},{ 0xa9,0} }, { { 0x2a,0},{ 0xaa,0} }, { { 0x2b,0},{ 0xab,0} }, /*028*/
|
|
{ { 0x2c,0},{ 0xac,0} }, { { 0x2d,0},{ 0xad,0} }, { { 0x2e,0},{ 0xae,0} }, { { 0x2f,0},{ 0xaf,0} }, /*02c*/
|
|
{ { 0x30,0},{ 0xb0,0} }, { { 0x31,0},{ 0xb1,0} }, { { 0x32,0},{ 0xb2,0} }, { { 0x33,0},{ 0xb3,0} }, /*030*/
|
|
{ { 0x34,0},{ 0xb4,0} }, { { 0x35,0},{ 0xb5,0} }, { { 0x36,0},{ 0xb6,0} }, { { 0x37,0},{ 0xb7,0} }, /*034*/
|
|
{ { 0x38,0},{ 0xb8,0} }, { { 0x39,0},{ 0xb9,0} }, { { 0x3a,0},{ 0xba,0} }, { { 0x3b,0},{ 0xbb,0} }, /*038*/
|
|
{ { 0x3c,0},{ 0xbc,0} }, { { 0x3d,0},{ 0xbd,0} }, { { 0x3e,0},{ 0xbe,0} }, { { 0x3f,0},{ 0xbf,0} }, /*03c*/
|
|
{ { 0x40,0},{ 0xc0,0} }, { { 0x41,0},{ 0xc1,0} }, { { 0x42,0},{ 0xc2,0} }, { { 0x43,0},{ 0xc3,0} }, /*040*/
|
|
{ { 0x44,0},{ 0xc4,0} }, { { 0x45,0},{ 0xc5,0} }, { { 0x46,0},{ 0xc6,0} }, { { 0x47,0},{ 0xc7,0} }, /*044*/
|
|
{ { 0x48,0},{ 0xc8,0} }, { { 0x49,0},{ 0xc9,0} }, { { 0x4a,0},{ 0xca,0} }, { { 0x4b,0},{ 0xcb,0} }, /*048*/
|
|
{ { 0x4c,0},{ 0xcc,0} }, { { 0x4d,0},{ 0xcd,0} }, { { 0x4e,0},{ 0xce,0} }, { { 0x4f,0},{ 0xcf,0} }, /*04c*/
|
|
{ { 0x50,0},{ 0xd0,0} }, { { 0x51,0},{ 0xd1,0} }, { { 0x52,0},{ 0xd2,0} }, { { 0x53,0},{ 0xd3,0} }, /*050*/
|
|
{ { 0x54,0},{ 0xd4,0} }, { { 0x55,0},{ 0xd5,0} }, { { 0x56,0},{ 0xd6,0} }, { { 0x57,0},{ 0xd7,0} }, /*054*/
|
|
{ { 0x58,0},{ 0xd8,0} }, { { 0x59,0},{ 0xd9,0} }, { { 0x5a,0},{ 0xda,0} }, { { 0x5b,0},{ 0xdb,0} }, /*058*/
|
|
{ { 0x5c,0},{ 0xdc,0} }, { { 0x5d,0},{ 0xdd,0} }, { { 0x5e,0},{ 0xde,0} }, { { 0x5f,0},{ 0xdf,0} }, /*05c*/
|
|
{ { 0x60,0},{ 0xe0,0} }, { { 0x61,0},{ 0xe1,0} }, { { 0x62,0},{ 0xe2,0} }, { { 0x63,0},{ 0xe3,0} }, /*060*/
|
|
{ { 0x64,0},{ 0xe4,0} }, { { 0x65,0},{ 0xe5,0} }, { { 0x66,0},{ 0xe6,0} }, { { 0x67,0},{ 0xe7,0} }, /*064*/
|
|
{ { 0x68,0},{ 0xe8,0} }, { { 0x69,0},{ 0xe9,0} }, { { 0x6a,0},{ 0xea,0} }, { { 0x6b,0},{ 0xeb,0} }, /*068*/
|
|
{ { 0x6c,0},{ 0xec,0} }, { { 0x6d,0},{ 0xed,0} }, { { 0x6e,0},{ 0xee,0} }, { { 0x6f,0},{ 0xef,0} }, /*06c*/
|
|
{ { 0x70,0},{ 0xf0,0} }, { { 0x71,0},{ 0xf1,0} }, { { 0x72,0},{ 0xf2,0} }, { { 0x73,0},{ 0xf3,0} }, /*070*/
|
|
{ { 0x74,0},{ 0xf4,0} }, { { 0x75,0},{ 0xf5,0} }, { { 0x76,0},{ 0xf6,0} }, { { 0x77,0},{ 0xf7,0} }, /*074*/
|
|
{ { 0x78,0},{ 0xf8,0} }, { { 0x79,0},{ 0xf9,0} }, { { 0x7a,0},{ 0xfa,0} }, { { 0x7b,0},{ 0xfb,0} }, /*078*/
|
|
{ { 0x7c,0},{ 0xfc,0} }, { { 0x7d,0},{ 0xfd,0} }, { { 0x7e,0},{ 0xfe,0} }, { { 0x7f,0},{ 0xff,0} }, /*07c*/
|
|
|
|
{ { 0x80,0},{ 0} }, { { 0x81,0},{ 0} }, { { 0x82,0},{ 0} }, { { 0},{ 0} }, /*080*/
|
|
{ { 0},{ 0} }, { { 0x85,0},{ 0} }, { { 0x86,0},{ 0} }, { { 0x87,0},{ 0} }, /*084*/
|
|
{ { 0x88,0},{ 0} }, { { 0x89,0},{ 0} }, { { 0x8a,0},{ 0} }, { { 0x8b,0},{ 0} }, /*088*/
|
|
{ { 0x8c,0},{ 0} }, { { 0x8d,0},{ 0} }, { { 0x8e,0},{ 0} }, { { 0x8f,0},{ 0} }, /*08c*/
|
|
{ { 0x90,0},{ 0} }, { { 0x91,0},{ 0} }, { { 0x92,0},{ 0} }, { { 0x93,0},{ 0} }, /*090*/
|
|
{ { 0x94,0},{ 0} }, { { 0x95,0},{ 0} }, { { 0x96,0},{ 0} }, { { 0x97,0},{ 0} }, /*094*/
|
|
{ { 0x98,0},{ 0} }, { { 0x99,0},{ 0} }, { { 0x9a,0},{ 0} }, { { 0x9b,0},{ 0} }, /*098*/
|
|
{ { 0x9c,0},{ 0} }, { { 0x9d,0},{ 0} }, { { 0x9e,0},{ 0} }, { { 0x9f,0},{ 0} }, /*09c*/
|
|
{ { 0xa0,0},{ 0} }, { { 0xa1,0},{ 0} }, { { 0xa2,0},{ 0} }, { { 0xa3,0},{ 0} }, /*0a0*/
|
|
{ { 0xa4,0},{ 0} }, { { 0xa5,0},{ 0} }, { { 0xa6,0},{ 0} }, { { 0xa7,0},{ 0} }, /*0a4*/
|
|
{ { 0xa8,0},{ 0} }, { { 0xa9,0},{ 0} }, { { 0xaa,0},{ 0} }, { { 0xab,0},{ 0} }, /*0a8*/
|
|
{ { 0xac,0},{ 0} }, { { 0xad,0},{ 0} }, { { 0xae,0},{ 0} }, { { 0xaf,0},{ 0} }, /*0ac*/
|
|
{ { 0xb0,0},{ 0} }, { { 0xb1,0},{ 0} }, { { 0xb2,0},{ 0} }, { { 0xb3,0},{ 0} }, /*0b0*/
|
|
{ { 0xb4,0},{ 0} }, { { 0xb5,0},{ 0} }, { { 0xb6,0},{ 0} }, { { 0xb7,0},{ 0} }, /*0b4*/
|
|
{ { 0xb8,0},{ 0} }, { { 0xb9,0},{ 0} }, { { 0xba,0},{ 0} }, { { 0xbb,0},{ 0} }, /*0b8*/
|
|
{ { 0xbc,0},{ 0} }, { { 0xbd,0},{ 0} }, { { 0xbe,0},{ 0} }, { { 0xbf,0},{ 0} }, /*0bc*/
|
|
{ { 0xc0,0},{ 0} }, { { 0xc1,0},{ 0} }, { { 0xc2,0},{ 0} }, { { 0xc3,0},{ 0} }, /*0c0*/
|
|
{ { 0xc4,0},{ 0} }, { { 0xc5,0},{ 0} }, { { 0xc6,0},{ 0} }, { { 0xc7,0},{ 0} }, /*0c4*/
|
|
{ { 0xc8,0},{ 0} }, { { 0xc9,0},{ 0} }, { { 0xca,0},{ 0} }, { { 0xcb,0},{ 0} }, /*0c8*/
|
|
{ { 0xcc,0},{ 0} }, { { 0xcd,0},{ 0} }, { { 0xce,0},{ 0} }, { { 0xcf,0},{ 0} }, /*0cc*/
|
|
{ { 0xd0,0},{ 0} }, { { 0xd1,0},{ 0} }, { { 0xd2,0},{ 0} }, { { 0xd3,0},{ 0} }, /*0d0*/
|
|
{ { 0xd4,0},{ 0} }, { { 0xd5,0},{ 0} }, { { 0xd6,0},{ 0} }, { { 0xd7,0},{ 0} }, /*0d4*/
|
|
{ { 0xd8,0},{ 0} }, { { 0xd9,0},{ 0} }, { { 0xda,0},{ 0} }, { { 0xdb,0},{ 0} }, /*0d8*/
|
|
{ { 0xdc,0},{ 0} }, { { 0xdd,0},{ 0} }, { { 0xde,0},{ 0} }, { { 0xdf,0},{ 0} }, /*0dc*/
|
|
{ { 0xe0,0},{ 0} }, { { 0xe1,0},{ 0} }, { { 0xe2,0},{ 0} }, { { 0xe3,0},{ 0} }, /*0e0*/
|
|
{ { 0xe4,0},{ 0} }, { { 0xe5,0},{ 0} }, { { 0xe6,0},{ 0} }, { { 0xe7,0},{ 0} }, /*0e4*/
|
|
{ { 0xe8,0},{ 0} }, { { 0xe9,0},{ 0} }, { { 0xea,0},{ 0} }, { { 0xeb,0},{ 0} }, /*0e8*/
|
|
{ { 0xec,0},{ 0} }, { { 0xed,0},{ 0} }, { { 0xee,0},{ 0} }, { { 0xef,0},{ 0} }, /*0ec*/
|
|
{ { 0},{ 0} }, { { 0xf1,0},{ 0} }, { { 0xf2,0},{ 0} }, { { 0xf3,0},{ 0} }, /*0f0*/
|
|
{ { 0xf4,0},{ 0} }, { { 0xf5,0},{ 0} }, { { 0xf6,0},{ 0} }, { { 0xf7,0},{ 0} }, /*0f4*/
|
|
{ { 0xf8,0},{ 0} }, { { 0xf9,0},{ 0} }, { { 0xfa,0},{ 0} }, { { 0xfb,0},{ 0} }, /*0f8*/
|
|
{ { 0xfc,0},{ 0} }, { { 0xfd,0},{ 0} }, { { 0xfe,0},{ 0} }, { { 0xff,0},{ 0} }, /*0fc*/
|
|
|
|
{ {0xe1,0x1d,0},{0xe1, 0x9d,0} }, { {0xe0,0x01,0},{0xe0, 0x81,0} }, { {0xe0,0x02,0},{0xe0, 0x82,0} }, { {0xe0,0x03,0},{0xe0, 0x83,0} }, /*100*/
|
|
{ {0xe0,0x04,0},{0xe0, 0x84,0} }, { {0xe0,0x05,0},{0xe0, 0x85,0} }, { {0xe0,0x06,0},{0xe0, 0x86,0} }, { {0xe0,0x07,0},{0xe0, 0x87,0} }, /*104*/
|
|
{ {0xe0,0x08,0},{0xe0, 0x88,0} }, { {0xe0,0x09,0},{0xe0, 0x89,0} }, { {0xe0,0x0a,0},{0xe0, 0x8a,0} }, { {0xe0,0x0b,0},{0xe0, 0x8b,0} }, /*108*/
|
|
{ {0xe0,0x0c,0},{0xe0, 0x8c,0} }, { { 0},{ 0} }, { {0xe0,0x0e,0},{0xe0, 0x8e,0} }, { {0xe0,0x0f,0},{0xe0, 0x8f,0} }, /*10c*/
|
|
{ {0xe0,0x10,0},{0xe0, 0x90,0} }, { {0xe0,0x11,0},{0xe0, 0x91,0} }, { {0xe0,0x12,0},{0xe0, 0x92,0} }, { {0xe0,0x13,0},{0xe0, 0x93,0} }, /*110*/
|
|
{ {0xe0,0x14,0},{0xe0, 0x94,0} }, { {0xe0,0x15,0},{0xe0, 0x95,0} }, { {0xe0,0x16,0},{0xe0, 0x96,0} }, { {0xe0,0x17,0},{0xe0, 0x97,0} }, /*114*/
|
|
{ {0xe0,0x18,0},{0xe0, 0x98,0} }, { {0xe0,0x19,0},{0xe0, 0x99,0} }, { {0xe0,0x1a,0},{0xe0, 0x9a,0} }, { {0xe0,0x1b,0},{0xe0, 0x9b,0} }, /*118*/
|
|
{ {0xe0,0x1c,0},{0xe0, 0x9c,0} }, { {0xe0,0x1d,0},{0xe0, 0x9d,0} }, { {0xe0,0x1e,0},{0xe0, 0x9e,0} }, { {0xe0,0x1f,0},{0xe0, 0x9f,0} }, /*11c*/
|
|
{ {0xe0,0x20,0},{0xe0, 0xa0,0} }, { {0xe0,0x21,0},{0xe0, 0xa1,0} }, { {0xe0,0x22,0},{0xe0, 0xa2,0} }, { {0xe0,0x23,0},{0xe0, 0xa3,0} }, /*120*/
|
|
{ {0xe0,0x24,0},{0xe0, 0xa4,0} }, { {0xe0,0x25,0},{0xe0, 0xa5,0} }, { {0xe0,0x26,0},{0xe0, 0xa6,0} }, { { 0},{ 0} }, /*124*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/
|
|
{ {0xe0,0x2c,0},{0xe0, 0xac,0} }, { {0xe0,0x2d,0},{0xe0, 0xad,0} }, { {0xe0,0x2e,0},{0xe0, 0xae,0} }, { {0xe0,0x2f,0},{0xe0, 0xaf,0} }, /*12c*/
|
|
{ {0xe0,0x30,0},{0xe0, 0xb0,0} }, { {0xe0,0x31,0},{0xe0, 0xb1,0} }, { {0xe0,0x32,0},{0xe0, 0xb2,0} }, { { 0},{ 0} }, /*130*/
|
|
{ {0xe0,0x34,0},{0xe0, 0xb4,0} }, { {0xe0,0x35,0},{0xe0, 0xb5,0} }, { { 0},{ 0} }, { {0xe0,0x37,0},{0xe0, 0xb7,0} }, /*134*/
|
|
{ {0xe0,0x38,0},{0xe0, 0xb8,0} }, { { 0},{ 0} }, { {0xe0,0x3a,0},{0xe0, 0xba,0} }, { {0xe0,0x3b,0},{0xe0, 0xbb,0} }, /*138*/
|
|
{ {0xe0,0x3c,0},{0xe0, 0xbc,0} }, { {0xe0,0x3d,0},{0xe0, 0xbd,0} }, { {0xe0,0x3e,0},{0xe0, 0xbe,0} }, { {0xe0,0x3f,0},{0xe0, 0xbf,0} }, /*13c*/
|
|
{ {0xe0,0x40,0},{0xe0, 0xc0,0} }, { {0xe0,0x41,0},{0xe0, 0xc1,0} }, { {0xe0,0x42,0},{0xe0, 0xc2,0} }, { {0xe0,0x43,0},{0xe0, 0xc3,0} }, /*140*/
|
|
{ {0xe0,0x44,0},{0xe0, 0xc4,0} }, { { 0},{ 0} }, { {0xe0,0x46,0},{0xe0, 0xc6,0} }, { {0xe0,0x47,0},{0xe0, 0xc7,0} }, /*144*/
|
|
{ {0xe0,0x48,0},{0xe0, 0xc8,0} }, { {0xe0,0x49,0},{0xe0, 0xc9,0} }, { { 0},{ 0} }, { {0xe0,0x4b,0},{0xe0, 0xcb,0} }, /*148*/
|
|
{ {0xe0,0x4c,0},{0xe0, 0xcc,0} }, { {0xe0,0x4d,0},{0xe0, 0xcd,0} }, { {0xe0,0x4e,0},{0xe0, 0xce,0} }, { {0xe0,0x4f,0},{0xe0, 0xcf,0} }, /*14c*/
|
|
{ {0xe0,0x50,0},{0xe0, 0xd0,0} }, { {0xe0,0x51,0},{0xe0, 0xd1,0} }, { {0xe0,0x52,0},{0xe0, 0xd2,0} }, { {0xe0,0x53,0},{0xe0, 0xd3,0} }, /*150*/
|
|
{ { 0},{ 0} }, { {0xe0,0x55,0},{0xe0, 0xd5,0} }, { { 0},{ 0} }, { {0xe0,0x57,0},{0xe0, 0xd7,0} }, /*154*/
|
|
{ {0xe0,0x58,0},{0xe0, 0xd8,0} }, { {0xe0,0x59,0},{0xe0, 0xd9,0} }, { {0xe0,0x5a,0},{0xe0, 0xaa,0} }, { {0xe0,0x5b,0},{0xe0, 0xdb,0} }, /*158*/
|
|
{ {0xe0,0x5c,0},{0xe0, 0xdc,0} }, { {0xe0,0x5d,0},{0xe0, 0xdd,0} }, { {0xe0,0x5e,0},{0xe0, 0xee,0} }, { {0xe0,0x5f,0},{0xe0, 0xdf,0} }, /*15c*/
|
|
{ { 0},{ 0} }, { {0xe0,0x61,0},{0xe0, 0xe1,0} }, { {0xe0,0x62,0},{0xe0, 0xe2,0} }, { {0xe0,0x63,0},{0xe0, 0xe3,0} }, /*160*/
|
|
{ {0xe0,0x64,0},{0xe0, 0xe4,0} }, { {0xe0,0x65,0},{0xe0, 0xe5,0} }, { {0xe0,0x66,0},{0xe0, 0xe6,0} }, { {0xe0,0x67,0},{0xe0, 0xe7,0} }, /*164*/
|
|
{ {0xe0,0x68,0},{0xe0, 0xe8,0} }, { {0xe0,0x69,0},{0xe0, 0xe9,0} }, { {0xe0,0x6a,0},{0xe0, 0xea,0} }, { {0xe0,0x6b,0},{0xe0, 0xeb,0} }, /*168*/
|
|
{ {0xe0,0x6c,0},{0xe0, 0xec,0} }, { {0xe0,0x6d,0},{0xe0, 0xed,0} }, { {0xe0,0x6e,0},{0xe0, 0xee,0} }, { { 0},{ 0} }, /*16c*/
|
|
{ {0xe0,0x70,0},{0xe0, 0xf0,0} }, { {0xe0,0x71,0},{0xe0, 0xf1,0} }, { {0xe0,0x72,0},{0xe0, 0xf2,0} }, { {0xe0,0x73,0},{0xe0, 0xf3,0} }, /*170*/
|
|
{ {0xe0,0x74,0},{0xe0, 0xf4,0} }, { {0xe0,0x75,0},{0xe0, 0xf5,0} }, { { 0},{ 0} }, { {0xe0,0x77,0},{0xe0, 0xf7,0} }, /*174*/
|
|
{ {0xe0,0x78,0},{0xe0, 0xf8,0} }, { {0xe0,0x79,0},{0xe0, 0xf9,0} }, { {0xe0,0x7a,0},{0xe0, 0xfa,0} }, { {0xe0,0x7b,0},{0xe0, 0xfb,0} }, /*178*/
|
|
{ {0xe0,0x7c,0},{0xe0, 0xfc,0} }, { {0xe0,0x7d,0},{0xe0, 0xfd,0} }, { {0xe0,0x7e,0},{0xe0, 0xfe,0} }, { {0xe0,0x7f,0},{0xe0, 0xff,0} }, /*17c*/
|
|
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/
|
|
{ { 0},{ 0} }, { {0xe0,0xe1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{ 0} }, { { 0},{ 0} }, /*1ec*/
|
|
{ { 0},{ 0} }, { {0xe0,0xf1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{ 0} }, { {0xe0,0xff,0},{ 0} } /*1fc*/
|
|
};
|
|
#endif
|
|
|
|
static const scancode scancode_set2[512] = {
|
|
{ { 0},{ 0} }, { { 0x76,0},{ 0xF0,0x76,0} }, { { 0x16,0},{ 0xF0,0x16,0} }, { { 0x1E,0},{ 0xF0,0x1E,0} }, /*000*/
|
|
{ { 0x26,0},{ 0xF0,0x26,0} }, { { 0x25,0},{ 0xF0,0x25,0} }, { { 0x2E,0},{ 0xF0,0x2E,0} }, { { 0x36,0},{ 0xF0,0x36,0} }, /*004*/
|
|
{ { 0x3D,0},{ 0xF0,0x3D,0} }, { { 0x3E,0},{ 0xF0,0x3E,0} }, { { 0x46,0},{ 0xF0,0x46,0} }, { { 0x45,0},{ 0xF0,0x45,0} }, /*008*/
|
|
{ { 0x4E,0},{ 0xF0,0x4E,0} }, { { 0x55,0},{ 0xF0,0x55,0} }, { { 0x66,0},{ 0xF0,0x66,0} }, { { 0x0D,0},{ 0xF0,0x0D,0} }, /*00c*/
|
|
{ { 0x15,0},{ 0xF0,0x15,0} }, { { 0x1D,0},{ 0xF0,0x1D,0} }, { { 0x24,0},{ 0xF0,0x24,0} }, { { 0x2D,0},{ 0xF0,0x2D,0} }, /*010*/
|
|
{ { 0x2C,0},{ 0xF0,0x2C,0} }, { { 0x35,0},{ 0xF0,0x35,0} }, { { 0x3C,0},{ 0xF0,0x3C,0} }, { { 0x43,0},{ 0xF0,0x43,0} }, /*014*/
|
|
{ { 0x44,0},{ 0xF0,0x44,0} }, { { 0x4D,0},{ 0xF0,0x4D,0} }, { { 0x54,0},{ 0xF0,0x54,0} }, { { 0x5B,0},{ 0xF0,0x5B,0} }, /*018*/
|
|
{ { 0x5A,0},{ 0xF0,0x5A,0} }, { { 0x14,0},{ 0xF0,0x14,0} }, { { 0x1C,0},{ 0xF0,0x1C,0} }, { { 0x1B,0},{ 0xF0,0x1B,0} }, /*01c*/
|
|
{ { 0x23,0},{ 0xF0,0x23,0} }, { { 0x2B,0},{ 0xF0,0x2B,0} }, { { 0x34,0},{ 0xF0,0x34,0} }, { { 0x33,0},{ 0xF0,0x33,0} }, /*020*/
|
|
{ { 0x3B,0},{ 0xF0,0x3B,0} }, { { 0x42,0},{ 0xF0,0x42,0} }, { { 0x4B,0},{ 0xF0,0x4B,0} }, { { 0x4C,0},{ 0xF0,0x4C,0} }, /*024*/
|
|
{ { 0x52,0},{ 0xF0,0x52,0} }, { { 0x0E,0},{ 0xF0,0x0E,0} }, { { 0x12,0},{ 0xF0,0x12,0} }, { { 0x5D,0},{ 0xF0,0x5D,0} }, /*028*/
|
|
{ { 0x1A,0},{ 0xF0,0x1A,0} }, { { 0x22,0},{ 0xF0,0x22,0} }, { { 0x21,0},{ 0xF0,0x21,0} }, { { 0x2A,0},{ 0xF0,0x2A,0} }, /*02c*/
|
|
{ { 0x32,0},{ 0xF0,0x32,0} }, { { 0x31,0},{ 0xF0,0x31,0} }, { { 0x3A,0},{ 0xF0,0x3A,0} }, { { 0x41,0},{ 0xF0,0x41,0} }, /*030*/
|
|
{ { 0x49,0},{ 0xF0,0x49,0} }, { { 0x4A,0},{ 0xF0,0x4A,0} }, { { 0x59,0},{ 0xF0,0x59,0} }, { { 0x7C,0},{ 0xF0,0x7C,0} }, /*034*/
|
|
{ { 0x11,0},{ 0xF0,0x11,0} }, { { 0x29,0},{ 0xF0,0x29,0} }, { { 0x58,0},{ 0xF0,0x58,0} }, { { 0x05,0},{ 0xF0,0x05,0} }, /*038*/
|
|
{ { 0x06,0},{ 0xF0,0x06,0} }, { { 0x04,0},{ 0xF0,0x04,0} }, { { 0x0C,0},{ 0xF0,0x0C,0} }, { { 0x03,0},{ 0xF0,0x03,0} }, /*03c*/
|
|
{ { 0x0B,0},{ 0xF0,0x0B,0} }, { { 0x83,0},{ 0xF0,0x83,0} }, { { 0x0A,0},{ 0xF0,0x0A,0} }, { { 0x01,0},{ 0xF0,0x01,0} }, /*040*/
|
|
{ { 0x09,0},{ 0xF0,0x09,0} }, { { 0x77,0},{ 0xF0,0x77,0} }, { { 0x7E,0},{ 0xF0,0x7E,0} }, { { 0x6C,0},{ 0xF0,0x6C,0} }, /*044*/
|
|
{ { 0x75,0},{ 0xF0,0x75,0} }, { { 0x7D,0},{ 0xF0,0x7D,0} }, { { 0x7B,0},{ 0xF0,0x7B,0} }, { { 0x6B,0},{ 0xF0,0x6B,0} }, /*048*/
|
|
{ { 0x73,0},{ 0xF0,0x73,0} }, { { 0x74,0},{ 0xF0,0x74,0} }, { { 0x79,0},{ 0xF0,0x79,0} }, { { 0x69,0},{ 0xF0,0x69,0} }, /*04c*/
|
|
{ { 0x72,0},{ 0xF0,0x72,0} }, { { 0x7A,0},{ 0xF0,0x7A,0} }, { { 0x70,0},{ 0xF0,0x70,0} }, { { 0x71,0},{ 0xF0,0x71,0} }, /*050*/
|
|
{ { 0x84,0},{ 0xF0,0x84,0} }, { { 0x60,0},{ 0xF0,0x60,0} }, { { 0x61,0},{ 0xF0,0x61,0} }, { { 0x78,0},{ 0xF0,0x78,0} }, /*054*/
|
|
{ { 0x07,0},{ 0xF0,0x07,0} }, { { 0x0F,0},{ 0xF0,0x0F,0} }, { { 0x17,0},{ 0xF0,0x17,0} }, { { 0x1F,0},{ 0xF0,0x1F,0} }, /*058*/
|
|
{ { 0x27,0},{ 0xF0,0x27,0} }, { { 0x2F,0},{ 0xF0,0x2F,0} }, { { 0x37,0},{ 0xF0,0x37,0} }, { { 0x3F,0},{ 0xF0,0x3F,0} }, /*05c*/
|
|
{ { 0x47,0},{ 0xF0,0x47,0} }, { { 0x4F,0},{ 0xF0,0x4F,0} }, { { 0x56,0},{ 0xF0,0x56,0} }, { { 0x5E,0},{ 0xF0,0x5E,0} }, /*060*/
|
|
{ { 0x08,0},{ 0xF0,0x08,0} }, { { 0x10,0},{ 0xF0,0x10,0} }, { { 0x18,0},{ 0xF0,0x18,0} }, { { 0x20,0},{ 0xF0,0x20,0} }, /*064*/
|
|
{ { 0x28,0},{ 0xF0,0x28,0} }, { { 0x30,0},{ 0xF0,0x30,0} }, { { 0x38,0},{ 0xF0,0x38,0} }, { { 0x40,0},{ 0xF0,0x40,0} }, /*068*/
|
|
{ { 0x48,0},{ 0xF0,0x48,0} }, { { 0x50,0},{ 0xF0,0x50,0} }, { { 0x57,0},{ 0xF0,0x57,0} }, { { 0x6F,0},{ 0xF0,0x6F,0} }, /*06c*/
|
|
{ { 0x13,0},{ 0xF0,0x13,0} }, { { 0x19,0},{ 0xF0,0x19,0} }, { { 0x39,0},{ 0xF0,0x39,0} }, { { 0x51,0},{ 0xF0,0x51,0} }, /*070*/
|
|
{ { 0x53,0},{ 0xF0,0x53,0} }, { { 0x5C,0},{ 0xF0,0x5C,0} }, { { 0x5F,0},{ 0xF0,0x5F,0} }, { { 0x62,0},{ 0xF0,0x62,0} }, /*074*/
|
|
{ { 0x63,0},{ 0xF0,0x63,0} }, { { 0x64,0},{ 0xF0,0x64,0} }, { { 0x65,0},{ 0xF0,0x65,0} }, { { 0x67,0},{ 0xF0,0x67,0} }, /*078*/
|
|
{ { 0x68,0},{ 0xF0,0x68,0} }, { { 0x6A,0},{ 0xF0,0x6A,0} }, { { 0x6D,0},{ 0xF0,0x6D,0} }, { { 0x6E,0},{ 0xF0,0x6E,0} }, /*07c*/
|
|
|
|
{ { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/
|
|
{ { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/
|
|
{ { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/
|
|
{ { 0x8c,0},{ 0xf0,0x8c,0} }, { { 0x8d,0},{ 0xf0,0x8d,0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/
|
|
{ { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/
|
|
{ { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/
|
|
{ { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/
|
|
{ { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/
|
|
{ { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/
|
|
{ { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/
|
|
{ { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/
|
|
{ { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/
|
|
{ { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/
|
|
{ { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/
|
|
{ { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/
|
|
{ { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/
|
|
{ { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/
|
|
{ { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/
|
|
{ { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/
|
|
{ { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/
|
|
{ { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/
|
|
{ { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/
|
|
{ { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/
|
|
{ { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/
|
|
{ { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/
|
|
{ { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/
|
|
{ { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/
|
|
{ { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/
|
|
{ { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/
|
|
{ { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/
|
|
{ { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/
|
|
{ { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/
|
|
|
|
{ {0xe1,0x14,0},{0xe1,0xf0,0x14,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/
|
|
{ {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/
|
|
{ {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/
|
|
{ {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/
|
|
{ {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/
|
|
{ {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/
|
|
{ {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/
|
|
{ {0xe0,0x5A,0},{0xe0,0xF0,0x5A,0} }, { {0xe0,0x14,0},{0xe0,0xF0,0x14,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/
|
|
{ {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/
|
|
{ {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/
|
|
{ {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/
|
|
{ {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/
|
|
{ {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { {0xe0,0x4A,0},{0xe0,0xF0,0x4A,0} }, { { 0},{ 0} }, { {0xe0,0x7C,0},{0xe0,0xF0,0x7C,0} }, /*134*/
|
|
{ {0xe0,0x11,0},{0xe0,0xF0,0x11,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/
|
|
{ {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/
|
|
{ {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/
|
|
{ {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { {0xe0,0x6C,0},{0xe0,0xF0,0x6C,0} }, /*144*/
|
|
{ {0xe0,0x75,0},{0xe0,0xF0,0x75,0} }, { {0xe0,0x7D,0},{0xe0,0xF0,0x7D,0} }, { { 0},{ 0} }, { {0xe0,0x6B,0},{0xe0,0xF0,0x6B,0} }, /*148*/
|
|
{ {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { {0xe0,0x74,0},{0xe0,0xF0,0x74,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { {0xe0,0x69,0},{0xe0,0xF0,0x69,0} }, /*14c*/
|
|
{ {0xe0,0x72,0},{0xe0,0xF0,0x72,0} }, { {0xe0,0x7A,0},{0xe0,0xF0,0x7A,0} }, { {0xe0,0x70,0},{0xe0,0xF0,0x70,0} }, { {0xe0,0x71,0},{0xe0,0xF0,0x71,0} }, /*150*/
|
|
{ { 0},{ 0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/
|
|
{ {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { {0xe0,0x1F,0},{0xe0,0xF0,0x1F,0} }, /*158*/
|
|
{ {0xe0,0x27,0},{0xe0,0xF0,0x27,0} }, { {0xe0,0x2F,0},{0xe0,0xF0,0x2F,0} }, { {0xe0,0x37,0},{0xe0,0xF0,0x37,0} }, { {0xe0,0x3F,0},{0xe0,0xF0,0x3F,0} }, /*15c*/
|
|
{ { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { {0xe0,0x5E,0},{0xe0,0xF0,0x5E,0} }, /*160*/
|
|
{ {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/
|
|
{ {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/
|
|
{ {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/
|
|
{ {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/
|
|
{ {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/
|
|
{ {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/
|
|
{ {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/
|
|
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/
|
|
{ { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/
|
|
{ { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/
|
|
};
|
|
|
|
static const scancode scancode_set3[512] = {
|
|
{ { 0},{ 0} }, { { 0x08,0},{ 0xf0,0x08,0} }, { { 0x16,0},{ 0xf0,0x16,0} }, { { 0x1E,0},{ 0xf0,0x1E,0} }, /*000*/
|
|
{ { 0x26,0},{ 0xf0,0x26,0} }, { { 0x25,0},{ 0xf0,0x25,0} }, { { 0x2E,0},{ 0xf0,0x2E,0} }, { { 0x36,0},{ 0xf0,0x36,0} }, /*004*/
|
|
{ { 0x3D,0},{ 0xf0,0x3D,0} }, { { 0x3E,0},{ 0xf0,0x3E,0} }, { { 0x46,0},{ 0xf0,0x46,0} }, { { 0x45,0},{ 0xf0,0x45,0} }, /*008*/
|
|
{ { 0x4E,0},{ 0xf0,0x4E,0} }, { { 0x55,0},{ 0xf0,0x55,0} }, { { 0x66,0},{ 0xf0,0x66,0} }, { { 0x0D,0},{ 0xf0,0x0D,0} }, /*00c*/
|
|
{ { 0x15,0},{ 0xf0,0x15,0} }, { { 0x1D,0},{ 0xf0,0x1D,0} }, { { 0x24,0},{ 0xf0,0x24,0} }, { { 0x2D,0},{ 0xf0,0x2D,0} }, /*010*/
|
|
{ { 0x2C,0},{ 0xf0,0x2C,0} }, { { 0x35,0},{ 0xf0,0x35,0} }, { { 0x3C,0},{ 0xf0,0x3C,0} }, { { 0x43,0},{ 0xf0,0x43,0} }, /*014*/
|
|
{ { 0x44,0},{ 0xf0,0x44,0} }, { { 0x4D,0},{ 0xf0,0x4D,0} }, { { 0x54,0},{ 0xf0,0x54,0} }, { { 0x5B,0},{ 0xf0,0x5B,0} }, /*018*/
|
|
{ { 0x5A,0},{ 0xf0,0x5A,0} }, { { 0x11,0},{ 0xf0,0x11,0} }, { { 0x1C,0},{ 0xf0,0x1C,0} }, { { 0x1B,0},{ 0xf0,0x1B,0} }, /*01c*/
|
|
{ { 0x23,0},{ 0xf0,0x23,0} }, { { 0x2B,0},{ 0xf0,0x2B,0} }, { { 0x34,0},{ 0xf0,0x34,0} }, { { 0x33,0},{ 0xf0,0x33,0} }, /*020*/
|
|
{ { 0x3B,0},{ 0xf0,0x3B,0} }, { { 0x42,0},{ 0xf0,0x42,0} }, { { 0x4B,0},{ 0xf0,0x4B,0} }, { { 0x4C,0},{ 0xf0,0x4C,0} }, /*024*/
|
|
{ { 0x52,0},{ 0xf0,0x52,0} }, { { 0x0E,0},{ 0xf0,0x0E,0} }, { { 0x12,0},{ 0xf0,0x12,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, /*028*/
|
|
{ { 0x1A,0},{ 0xf0,0x1A,0} }, { { 0x22,0},{ 0xf0,0x22,0} }, { { 0x21,0},{ 0xf0,0x21,0} }, { { 0x2A,0},{ 0xf0,0x2A,0} }, /*02c*/
|
|
{ { 0x32,0},{ 0xf0,0x32,0} }, { { 0x31,0},{ 0xf0,0x31,0} }, { { 0x3A,0},{ 0xf0,0x3A,0} }, { { 0x41,0},{ 0xf0,0x41,0} }, /*030*/
|
|
{ { 0x49,0},{ 0xf0,0x49,0} }, { { 0x4A,0},{ 0xf0,0x4A,0} }, { { 0x59,0},{ 0xf0,0x59,0} }, { { 0x7E,0},{ 0xf0,0x7E,0} }, /*034*/
|
|
{ { 0x19,0},{ 0xf0,0x19,0} }, { { 0x29,0},{ 0xf0,0x29,0} }, { { 0x14,0},{ 0xf0,0x14,0} }, { { 0x07,0},{ 0xf0,0x07,0} }, /*038*/
|
|
{ { 0x0F,0},{ 0xf0,0x0F,0} }, { { 0x17,0},{ 0xf0,0x17,0} }, { { 0x1F,0},{ 0xf0,0x1F,0} }, { { 0x27,0},{ 0xf0,0x27,0} }, /*03c*/
|
|
{ { 0x2F,0},{ 0xf0,0x2F,0} }, { { 0x37,0},{ 0xf0,0x37,0} }, { { 0x3F,0},{ 0xf0,0x3F,0} }, { { 0x47,0},{ 0xf0,0x47,0} }, /*040*/
|
|
{ { 0x4F,0},{ 0xf0,0x4F,0} }, { { 0x76,0},{ 0xf0,0x76,0} }, { { 0x5F,0},{ 0xf0,0x5F,0} }, { { 0x6C,0},{ 0xf0,0x6C,0} }, /*044*/
|
|
{ { 0x75,0},{ 0xf0,0x75,0} }, { { 0x7D,0},{ 0xf0,0x7D,0} }, { { 0x84,0},{ 0xf0,0x84,0} }, { { 0x6B,0},{ 0xf0,0x6B,0} }, /*048*/
|
|
{ { 0x73,0},{ 0xf0,0x73,0} }, { { 0x74,0},{ 0xf0,0x74,0} }, { { 0x7C,0},{ 0xf0,0x7C,0} }, { { 0x69,0},{ 0xf0,0x69,0} }, /*04c*/
|
|
{ { 0x72,0},{ 0xf0,0x72,0} }, { { 0x7A,0},{ 0xf0,0x7A,0} }, { { 0x70,0},{ 0xf0,0x70,0} }, { { 0x71,0},{ 0xf0,0x71,0} }, /*050*/
|
|
{ { 0x57,0},{ 0xf0,0x57,0} }, { { 0x60,0},{ 0xf0,0x60,0} }, { { 0},{ 0} }, { { 0x56,0},{ 0xf0,0x56,0} }, /*054*/
|
|
{ { 0x5E,0},{ 0xf0,0x5E,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*058*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*05c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*060*/
|
|
{ { 0},{ 0} }, { { 0x10,0},{ 0xf0,0x10,0} }, { { 0x18,0},{ 0xf0,0x18,0} }, { { 0x20,0},{ 0xf0,0x20,0} }, /*064*/
|
|
{ { 0x28,0},{ 0xf0,0x28,0} }, { { 0x30,0},{ 0xf0,0x30,0} }, { { 0x38,0},{ 0xf0,0x38,0} }, { { 0x40,0},{ 0xf0,0x40,0} }, /*068*/
|
|
{ { 0x48,0},{ 0xf0,0x48,0} }, { { 0x50,0},{ 0xf0,0x50,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*06c*/
|
|
{ { 0x87,0},{ 0xf0,0x87,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0x51,0},{ 0xf0,0x51,0} }, /*070*/
|
|
{ { 0x53,0},{ 0xf0,0x53,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, { { 0},{ 0} }, { { 0x62,0},{ 0xf0,0x62,0} }, /*074*/
|
|
{ { 0x63,0},{ 0xf0,0x63,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x85,0} }, /*078*/
|
|
{ { 0x68,0},{ 0xf0,0x68,0} }, { { 0x13,0},{ 0xf0,0x13,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*07c*/
|
|
|
|
{ { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/
|
|
{ { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/
|
|
{ { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/
|
|
{ { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/
|
|
{ { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/
|
|
{ { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/
|
|
{ { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/
|
|
{ { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/
|
|
{ { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/
|
|
{ { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/
|
|
{ { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/
|
|
{ { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/
|
|
{ { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/
|
|
{ { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/
|
|
{ { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/
|
|
{ { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/
|
|
{ { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/
|
|
{ { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/
|
|
{ { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/
|
|
{ { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/
|
|
{ { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/
|
|
{ { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/
|
|
{ { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/
|
|
{ { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/
|
|
{ { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/
|
|
{ { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/
|
|
{ { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/
|
|
{ { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/
|
|
{ { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/
|
|
{ { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/
|
|
{ { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/
|
|
|
|
{ { 0x62,0},{ 0xF0,0x62,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/
|
|
{ {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/
|
|
{ {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/
|
|
{ {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/
|
|
{ {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/
|
|
{ {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/
|
|
{ {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/
|
|
{ { 0x79,0},{ 0xf0,0x79,0} }, { { 0x58,0},{ 0xf0,0x58,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/
|
|
{ {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/
|
|
{ {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/
|
|
{ {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/
|
|
{ {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/
|
|
{ {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { { 0x77,0},{ 0xf0,0x77,0} }, { { 0},{ 0} }, { { 0x57,0},{ 0xf0,0x57,0} }, /*134*/
|
|
{ { 0x39,0},{ 0xf0,0x39,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/
|
|
{ {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/
|
|
{ {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/
|
|
{ {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { { 0x6E,0},{ 0xf0,0x6E,0} }, /*144*/
|
|
{ { 0x63,0},{ 0xf0,0x63,0} }, { { 0x6F,0},{ 0xf0,0x6F,0} }, { { 0},{ 0} }, { { 0x61,0},{ 0xf0,0x61,0} }, /*148*/
|
|
{ {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { { 0x6A,0},{ 0xf0,0x6A,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { { 0x65,0},{ 0xf0,0x65,0} }, /*14c*/
|
|
{ { 0x60,0},{ 0xf0,0x60,0} }, { { 0x6D,0},{ 0xf0,0x6D,0} }, { { 0x67,0},{ 0xf0,0x67,0} }, { { 0x64,0},{ 0xf0,0x64,0} }, /*150*/
|
|
{ { 0xd4,0},{ 0xf0,0xD4,0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/
|
|
{ {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { { 0x8B,0},{ 0xf0,0x8B,0} }, /*158*/
|
|
{ { 0x8C,0},{ 0xf0,0x8C,0} }, { { 0x8D,0},{ 0xf0,0x8D,0} }, { { 0},{ 0} }, { { 0x7F,0},{ 0xf0,0x7F,0} }, /*15c*/
|
|
{ { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { { 0},{ 0} }, /*160*/
|
|
{ {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/
|
|
{ {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/
|
|
{ {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/
|
|
{ {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/
|
|
{ {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/
|
|
{ {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/
|
|
{ {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/
|
|
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/
|
|
{ { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/
|
|
{ { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/
|
|
{ { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/
|
|
};
|
|
|
|
|
|
static void add_data_kbd(uint16_t val);
|
|
|
|
|
|
#ifdef ENABLE_KEYBOARD_AT_LOG
|
|
int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG;
|
|
|
|
|
|
static void
|
|
kbd_log(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
if (keyboard_at_do_log) {
|
|
va_start(ap, fmt);
|
|
pclog_ex(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
}
|
|
#else
|
|
#define kbd_log(fmt, ...)
|
|
#endif
|
|
|
|
|
|
static void
|
|
set_scancode_map(atkbd_t *dev)
|
|
{
|
|
switch (keyboard_mode & 3) {
|
|
#ifdef USE_SET1
|
|
case 1:
|
|
default:
|
|
keyboard_set_table(scancode_set1);
|
|
break;
|
|
#else
|
|
default:
|
|
#endif
|
|
case 2:
|
|
keyboard_set_table(scancode_set2);
|
|
break;
|
|
|
|
case 3:
|
|
keyboard_set_table(scancode_set3);
|
|
break;
|
|
}
|
|
|
|
if (keyboard_mode & 0x20)
|
|
#ifdef USE_SET1
|
|
keyboard_set_table(scancode_set1);
|
|
#else
|
|
keyboard_set_table(scancode_set2);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
kbc_queue_reset(uint8_t channel)
|
|
{
|
|
if (channel == 2) {
|
|
mouse_queue_start = mouse_queue_end = 0;
|
|
memset(mouse_queue, 0x00, sizeof(mouse_queue));
|
|
} else if (channel == 1) {
|
|
key_queue_start = key_queue_end = 0;
|
|
memset(key_queue, 0x00, sizeof(key_queue));
|
|
} else {
|
|
key_ctrl_queue_start = key_ctrl_queue_end = 0;
|
|
memset(key_ctrl_queue, 0x00, sizeof(key_ctrl_queue));
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
|
{
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF))
|
|
stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00);
|
|
else
|
|
stat_hi |= 0x10;
|
|
|
|
dev->status = (dev->status & 0x0f) | stat_hi;
|
|
|
|
if (channel == 2) {
|
|
kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val);
|
|
mouse_queue[mouse_queue_end] = val;
|
|
mouse_queue_end = (mouse_queue_end + 1) & 0xf;
|
|
} else if (channel == 1) {
|
|
kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val);
|
|
key_queue[key_queue_end] = val;
|
|
key_queue_end = (key_queue_end + 1) & 0xf;
|
|
} else {
|
|
kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val);
|
|
key_ctrl_queue[key_ctrl_queue_end] = val;
|
|
key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
add_to_kbc_queue_front(atkbd_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
|
{
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF))
|
|
stat_hi |= ((dev->input_port & 0x80) ? 0x10 : 0x00);
|
|
else
|
|
stat_hi |= 0x10;
|
|
|
|
kbd_log("ATkbc: Adding %02X to front...\n", val);
|
|
dev->wantirq = 0;
|
|
if (channel == 2) {
|
|
if (dev->mem[0] & 0x02)
|
|
picint(0x1000);
|
|
if (kbc_ven != KBC_VEN_OLIVETTI)
|
|
dev->last_irq = 0x1000;
|
|
} else {
|
|
if (dev->mem[0] & 0x01)
|
|
picint(2);
|
|
if (kbc_ven != KBC_VEN_OLIVETTI)
|
|
dev->last_irq = 2;
|
|
}
|
|
dev->out = val;
|
|
if (channel == 2)
|
|
dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL) | stat_hi;
|
|
else
|
|
dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL | stat_hi;
|
|
if (kbc_ven == KBC_VEN_OLIVETTI)
|
|
dev->last_irq = 0x0000;
|
|
}
|
|
|
|
|
|
static void
|
|
add_data_kbd_queue(atkbd_t *dev, int direct, uint8_t val)
|
|
{
|
|
if ((!keyboard_scan && !direct) || (dev->reset_delay > 0) || (key_queue_end >= 16)) {
|
|
kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (key_queue_end >= 16));
|
|
return;
|
|
}
|
|
kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val);
|
|
kbc_queue_add(dev, val, 1, 0x00);
|
|
kbd_last_scan_code = val;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
add_data_kbd_direct(atkbd_t *dev, uint8_t val)
|
|
{
|
|
int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF);
|
|
int translate = (keyboard_mode & 0x40);
|
|
uint8_t send;
|
|
|
|
if (dev->reset_delay)
|
|
return;
|
|
|
|
translate = translate || (keyboard_mode & 0x40) || xt_mode;
|
|
translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2);
|
|
|
|
if (translate)
|
|
send = nont_to_t[val];
|
|
else
|
|
send = val;
|
|
|
|
add_data_kbd_queue(dev, 1, send);
|
|
}
|
|
|
|
|
|
static void
|
|
add_data_kbd_raw(atkbd_t *dev, uint8_t val)
|
|
{
|
|
add_data_kbd_queue(dev, 1, val);
|
|
}
|
|
|
|
|
|
static void
|
|
kbd_poll(void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
#ifdef ENABLE_KEYBOARD_AT_LOG
|
|
const uint8_t channels[4] = { 1, 2, 0, 0 };
|
|
#endif
|
|
|
|
timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC));
|
|
|
|
if (dev->out_new != -1 && !dev->last_irq) {
|
|
dev->wantirq = 0;
|
|
if (dev->out_new & 0x100) {
|
|
if (dev->mem[0] & 0x02)
|
|
picint(0x1000);
|
|
kbd_log("ATkbc: %02X coming from channel 2\n");
|
|
dev->out = dev->out_new & 0xff;
|
|
dev->out_new = -1;
|
|
dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL);
|
|
dev->last_irq = 0x1000;
|
|
} else {
|
|
if (dev->mem[0] & 0x01)
|
|
picint(2);
|
|
kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03]);
|
|
dev->out = dev->out_new & 0xff;
|
|
dev->out_new = -1;
|
|
dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL;
|
|
dev->last_irq = 2;
|
|
}
|
|
}
|
|
|
|
if (dev->out_new == -1 && !(dev->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) {
|
|
kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]);
|
|
dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200;
|
|
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf;
|
|
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && dev->out_delayed != -1) {
|
|
kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]);
|
|
dev->out_new = dev->out_delayed;
|
|
dev->out_delayed = -1;
|
|
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_queue_start != mouse_queue_end) {
|
|
kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]);
|
|
dev->out_new = mouse_queue[mouse_queue_start] | 0x100;
|
|
mouse_queue_start = (mouse_queue_start + 1) & 0xf;
|
|
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0] & 0x10) && key_queue_start != key_queue_end) {
|
|
kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]);
|
|
dev->out_new = key_queue[key_queue_start];
|
|
key_queue_start = (key_queue_start + 1) & 0xf;
|
|
}
|
|
|
|
if (dev->reset_delay) {
|
|
dev->reset_delay--;
|
|
if (!dev->reset_delay) {
|
|
kbd_log("ATkbc: Sending AA on keyboard reset...\n");
|
|
add_data_kbd_direct(dev, 0xaa);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
add_data(atkbd_t *dev, uint8_t val)
|
|
{
|
|
kbd_log("ATkbc: add to queue\n");
|
|
|
|
kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val);
|
|
kbc_queue_add(dev, val, 0, 0x00);
|
|
|
|
if (!(dev->out_new & 0x300)) {
|
|
dev->out_delayed = dev->out_new;
|
|
dev->out_new = -1;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len)
|
|
{
|
|
int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF);
|
|
int translate = (keyboard_mode & 0x40);
|
|
int i;
|
|
uint8_t or = 0;
|
|
uint8_t send;
|
|
|
|
if (dev->reset_delay)
|
|
return;
|
|
|
|
translate = translate || (keyboard_mode & 0x40) || xt_mode;
|
|
translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2);
|
|
|
|
for (i = 0; i < len; i++) {
|
|
if (translate) {
|
|
if (val[i] == 0xf0) {
|
|
or = 0x80;
|
|
continue;
|
|
}
|
|
send = nont_to_t[val[i]] | or;
|
|
if (or == 0x80)
|
|
or = 0;
|
|
} else
|
|
send = val[i];
|
|
|
|
add_data_kbd_queue(dev, 0, send);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
add_data_kbd(uint16_t val)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
int xt_mode = (keyboard_mode & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF);
|
|
int translate = (keyboard_mode & 0x40);
|
|
uint8_t fake_shift[4];
|
|
uint8_t num_lock = 0, shift_states = 0;
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
if (dev->reset_delay)
|
|
return;
|
|
|
|
translate = translate || (keyboard_mode & 0x40) || xt_mode;
|
|
translate = translate || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2);
|
|
|
|
keyboard_get_states(NULL, &num_lock, NULL);
|
|
shift_states = keyboard_get_shift() & STATE_SHIFT_MASK;
|
|
|
|
/* Allow for scan code translation. */
|
|
if (translate && (val == 0xf0)) {
|
|
kbd_log("ATkbd: translate is on, F0 prefix detected\n");
|
|
sc_or = 0x80;
|
|
return;
|
|
}
|
|
|
|
/* Skip break code if translated make code has bit 7 set. */
|
|
if (translate && (sc_or == 0x80) && (val & 0x80)) {
|
|
kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val);
|
|
sc_or = 0;
|
|
return;
|
|
}
|
|
|
|
/* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */
|
|
if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) &&
|
|
(keyboard_recv(0xb8) || keyboard_recv(0x9d))) switch (val) {
|
|
case 0x4f: t3100e_notify_set(0x01); break; /* End */
|
|
case 0x50: t3100e_notify_set(0x02); break; /* Down */
|
|
case 0x51: t3100e_notify_set(0x03); break; /* PgDn */
|
|
case 0x52: t3100e_notify_set(0x04); break; /* Ins */
|
|
case 0x53: t3100e_notify_set(0x05); break; /* Del */
|
|
case 0x54: t3100e_notify_set(0x06); break; /* SysRQ */
|
|
case 0x45: t3100e_notify_set(0x07); break; /* NumLock */
|
|
case 0x46: t3100e_notify_set(0x08); break; /* ScrLock */
|
|
case 0x47: t3100e_notify_set(0x09); break; /* Home */
|
|
case 0x48: t3100e_notify_set(0x0a); break; /* Up */
|
|
case 0x49: t3100e_notify_set(0x0b); break; /* PgUp */
|
|
case 0x4A: t3100e_notify_set(0x0c); break; /* Keypad -*/
|
|
case 0x4B: t3100e_notify_set(0x0d); break; /* Left */
|
|
case 0x4C: t3100e_notify_set(0x0e); break; /* KP 5 */
|
|
case 0x4D: t3100e_notify_set(0x0f); break; /* Right */
|
|
}
|
|
|
|
kbd_log("ATkbd: translate is %s, ", translate ? "on" : "off");
|
|
switch(val) {
|
|
case FAKE_LSHIFT_ON:
|
|
kbd_log("fake left shift on, scan code: ");
|
|
if (num_lock) {
|
|
if (shift_states) {
|
|
kbd_log("N/A (one or both shifts on)\n");
|
|
break;
|
|
} else {
|
|
/* Num lock on and no shifts are pressed, send non-inverted fake shift. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x2a;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x12;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if (shift_states & STATE_LSHIFT) {
|
|
/* Num lock off and left shift pressed. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xaa;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12;
|
|
add_data_vals(dev, fake_shift, 3);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
if (shift_states & STATE_RSHIFT) {
|
|
/* Num lock off and right shift pressed. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xb6;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59;
|
|
add_data_vals(dev, fake_shift, 3);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
kbd_log(shift_states ? "" : "N/A (both shifts off)\n");
|
|
}
|
|
break;
|
|
|
|
case FAKE_LSHIFT_OFF:
|
|
kbd_log("fake left shift on, scan code: ");
|
|
if (num_lock) {
|
|
if (shift_states) {
|
|
kbd_log("N/A (one or both shifts on)\n");
|
|
break;
|
|
} else {
|
|
/* Num lock on and no shifts are pressed, send non-inverted fake shift. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xaa;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12;
|
|
add_data_vals(dev, fake_shift, 3);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if (shift_states & STATE_LSHIFT) {
|
|
/* Num lock off and left shift pressed. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x2a;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x12;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
if (shift_states & STATE_RSHIFT) {
|
|
/* Num lock off and right shift pressed. */
|
|
switch(keyboard_mode & 0x02) {
|
|
case 1:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x36;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
case 2:
|
|
fake_shift[0] = 0xe0; fake_shift[1] = 0x59;
|
|
add_data_vals(dev, fake_shift, 2);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("N/A (scan code set %i)\n", keyboard_mode & 0x02);
|
|
break;
|
|
}
|
|
}
|
|
kbd_log(shift_states ? "" : "N/A (both shifts off)\n");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
#ifdef ENABLE_KEYBOARD_AT_LOG
|
|
kbd_log("scan code: ");
|
|
if (translate) {
|
|
kbd_log("%02X (original: ", (nont_to_t[val] | sc_or));
|
|
if (sc_or == 0x80)
|
|
kbd_log("F0 ");
|
|
kbd_log("%02X)\n", val);
|
|
} else
|
|
kbd_log("%02X\n", val);
|
|
#endif
|
|
|
|
add_data_kbd_queue(dev, 0, translate ? (nont_to_t[val] | sc_or) : val);
|
|
break;
|
|
}
|
|
|
|
if (sc_or == 0x80)
|
|
sc_or = 0;
|
|
}
|
|
|
|
|
|
static void
|
|
write_output(atkbd_t *dev, uint8_t val)
|
|
{
|
|
uint8_t old = dev->output_port;
|
|
kbd_log("ATkbc: write output port: %02X (old: %02X)\n", val, dev->output_port);
|
|
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
if ((kbc_ven != KBC_VEN_OLIVETTI) && ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)))
|
|
val |= ((dev->mem[0] << 4) & 0x10);
|
|
|
|
/*IRQ 12*/
|
|
if ((dev->output_port ^ val) & 0x20) {
|
|
if (val & 0x20)
|
|
picint(1 << 12);
|
|
else
|
|
picintc(1 << 12);
|
|
}
|
|
|
|
/*IRQ 1*/
|
|
if ((dev->output_port ^ val) & 0x10) {
|
|
if (val & 0x10)
|
|
picint(1 << 1);
|
|
else
|
|
picintc(1 << 1);
|
|
}
|
|
|
|
if ((dev->output_port ^ val) & 0x02) { /*A20 enable change*/
|
|
mem_a20_key = val & 0x02;
|
|
mem_a20_recalc();
|
|
flushmmucache();
|
|
}
|
|
|
|
/* 0 holds the CPU in the RESET state, 1 releases it. To simplify this,
|
|
we just do everything on release. */
|
|
if ((dev->output_port ^ val) & 0x01) { /*Reset*/
|
|
if (! (val & 0x01)) { /* Pin 0 selected. */
|
|
/* Pin 0 selected. */
|
|
kbd_log("write_output(): Pulse reset!\n");
|
|
softresetx86(); /*Pulse reset!*/
|
|
cpu_set_edx();
|
|
flushmmucache();
|
|
}
|
|
}
|
|
|
|
/* Do this here to avoid an infinite reset loop. */
|
|
dev->output_port = val;
|
|
}
|
|
|
|
|
|
static void
|
|
write_cmd(atkbd_t *dev, uint8_t val)
|
|
{
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0]);
|
|
|
|
if ((val & 1) && (dev->status & STAT_OFULL))
|
|
dev->wantirq = 1;
|
|
if (!(val & 1) && dev->wantirq)
|
|
dev->wantirq = 0;
|
|
|
|
/* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */
|
|
if ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) {
|
|
val &= ~CCB_TRANSLATE;
|
|
dev->mem[0] &= ~CCB_TRANSLATE;
|
|
}
|
|
|
|
/* Scan code translate ON/OFF. */
|
|
keyboard_mode &= 0x93;
|
|
keyboard_mode |= (val & MODE_MASK);
|
|
|
|
kbd_log("ATkbc: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled");
|
|
|
|
/* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT);
|
|
PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch.
|
|
The AMIKEY firmware apparently uses this bit for something else. */
|
|
if ((kbc_ven == KBC_VEN_AMI) ||
|
|
((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) {
|
|
keyboard_mode &= ~CCB_PCMODE;
|
|
|
|
kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled");
|
|
}
|
|
|
|
if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF)) {
|
|
/* Update the output port to mirror the KBD DIS and AUX DIS bits, if active. */
|
|
write_output(dev, dev->output_port);
|
|
}
|
|
|
|
kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0], val);
|
|
|
|
dev->status = (dev->status & ~STAT_SYSFLAG) | (val & STAT_SYSFLAG);
|
|
}
|
|
|
|
|
|
static void
|
|
pulse_output(atkbd_t *dev, uint8_t mask)
|
|
{
|
|
if (mask != 0x0f) {
|
|
dev->old_output_port = dev->output_port & ~(0xf0 | mask);
|
|
kbd_log("pulse_output(): Output port now: %02X\n", dev->output_port & (0xf0 | mask));
|
|
write_output(dev, dev->output_port & (0xf0 | mask));
|
|
timer_set_delay_u64(&dev->pulse_cb, 6ULL * TIMER_USEC);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
pulse_poll(void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
kbd_log("pulse_poll(): Output port now: %02X\n", dev->output_port | dev->old_output_port);
|
|
write_output(dev, dev->output_port | dev->old_output_port);
|
|
}
|
|
|
|
|
|
static void
|
|
set_enable_kbd(atkbd_t *dev, uint8_t enable)
|
|
{
|
|
dev->mem[0] &= 0xef;
|
|
dev->mem[0] |= (enable ? 0x00 : 0x10);
|
|
}
|
|
|
|
|
|
static void
|
|
set_enable_mouse(atkbd_t *dev, uint8_t enable)
|
|
{
|
|
dev->mem[0] &= 0xdf;
|
|
dev->mem[0] |= (enable ? 0x00 : 0x20);
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write64_generic(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
uint8_t current_drive, fixed_bits;
|
|
uint8_t kbc_ven = 0x0;
|
|
kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
|
|
switch (val) {
|
|
case 0xa4: /* check if password installed */
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: check if password installed\n");
|
|
add_data(dev, 0xf1);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa7: /* disable mouse port */
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: disable mouse port\n");
|
|
set_enable_mouse(dev, 0);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa8: /*Enable mouse port*/
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: enable mouse port\n");
|
|
set_enable_mouse(dev, 1);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa9: /*Test mouse port*/
|
|
kbd_log("ATkbc: test mouse port\n");
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
add_data(dev, 0x00); /* no error, this is testing the channel 2 interface */
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xaf: /* read keyboard version */
|
|
kbd_log("ATkbc: read keyboard version\n");
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xc0: /* read input port */
|
|
kbd_log("ATkbc: read input port\n");
|
|
fixed_bits = 4;
|
|
/* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */
|
|
if (kbc_ven == KBC_VEN_INTEL_AMI)
|
|
fixed_bits |= 0x40;
|
|
if (kbc_ven == KBC_VEN_IBM_PS1) {
|
|
current_drive = fdc_get_current_drive();
|
|
add_to_kbc_queue_front(dev, dev->input_port | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00),
|
|
0, 0x00);
|
|
dev->input_port = ((dev->input_port + 1) & 3) |
|
|
(dev->input_port & 0xfc) |
|
|
(fdd_is_525(current_drive) ? 0x40 : 0x00);
|
|
} else if (kbc_ven == KBC_VEN_NCR) {
|
|
/* switch settings
|
|
* bit 7: keyboard disable
|
|
* bit 6: display type (0 color, 1 mono)
|
|
* bit 5: power-on default speed (0 high, 1 low)
|
|
* bit 4: sense RAM size (0 unsupported, 1 512k on system board)
|
|
* bit 3: coprocessor detect
|
|
* bit 2: unused
|
|
* bit 1: high/auto speed
|
|
* bit 0: dma mode
|
|
*/
|
|
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf,
|
|
0, 0x00);
|
|
dev->input_port = ((dev->input_port + 1) & 3) |
|
|
(dev->input_port & 0xfc);
|
|
} else {
|
|
if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) &&
|
|
((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI))
|
|
#if 0
|
|
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits) &
|
|
(((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0xeb : 0xef), 0, 0x00);
|
|
#else
|
|
add_to_kbc_queue_front(dev, ((dev->input_port | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00);
|
|
#endif
|
|
else
|
|
add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00);
|
|
dev->input_port = ((dev->input_port + 1) & 3) |
|
|
(dev->input_port & 0xfc);
|
|
}
|
|
return 0;
|
|
|
|
case 0xd3: /* write mouse output buffer */
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: write mouse output buffer\n");
|
|
dev->want60 = 1;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xd4: /* write to mouse */
|
|
kbd_log("ATkbc: write to mouse\n");
|
|
dev->want60 = 1;
|
|
return 0;
|
|
|
|
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
|
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
|
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
|
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
|
kbd_log("ATkbc: pulse %01X\n", val & 0x0f);
|
|
pulse_output(dev, val & 0x0f);
|
|
return 0;
|
|
}
|
|
|
|
kbd_log("ATkbc: bad command %02X\n", val);
|
|
return 1;
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write60_ami(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch(dev->command) {
|
|
/* 0x40 - 0x5F are aliases for 0x60-0x7F */
|
|
case 0x40: case 0x41: case 0x42: case 0x43:
|
|
case 0x44: case 0x45: case 0x46: case 0x47:
|
|
case 0x48: case 0x49: case 0x4a: case 0x4b:
|
|
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
|
case 0x50: case 0x51: case 0x52: case 0x53:
|
|
case 0x54: case 0x55: case 0x56: case 0x57:
|
|
case 0x58: case 0x59: case 0x5a: case 0x5b:
|
|
case 0x5c: case 0x5d: case 0x5e: case 0x5f:
|
|
kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command);
|
|
dev->mem[dev->command & 0x1f] = val;
|
|
if (dev->command == 0x60)
|
|
write_cmd(dev, val);
|
|
return 0;
|
|
|
|
case 0xaf: /* set extended controller RAM */
|
|
kbd_log("ATkbc: AMI - set extended controller RAM\n");
|
|
if (dev->secr_phase == 1) {
|
|
dev->mem_addr = val;
|
|
dev->want60 = 1;
|
|
dev->secr_phase = 2;
|
|
} else if (dev->secr_phase == 2) {
|
|
dev->mem[dev->mem_addr] = val;
|
|
dev->secr_phase = 0;
|
|
}
|
|
return 0;
|
|
|
|
case 0xc1:
|
|
kbd_log("ATkbc: AMI MegaKey - write %02X to input port\n", val);
|
|
dev->input_port = val;
|
|
return 0;
|
|
|
|
case 0xcb: /* set keyboard mode */
|
|
kbd_log("ATkbc: AMI - set keyboard mode\n");
|
|
dev->ami_flags = val;
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write64_ami(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch (val) {
|
|
case 0x00: case 0x01: case 0x02: case 0x03:
|
|
case 0x04: case 0x05: case 0x06: case 0x07:
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
|
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
case 0x10: case 0x11: case 0x12: case 0x13:
|
|
case 0x14: case 0x15: case 0x16: case 0x17:
|
|
case 0x18: case 0x19: case 0x1a: case 0x1b:
|
|
case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
|
kbd_log("ATkbc: AMI - alias read from %08X\n", val);
|
|
add_data(dev, dev->mem[val]);
|
|
return 0;
|
|
|
|
case 0x40: case 0x41: case 0x42: case 0x43:
|
|
case 0x44: case 0x45: case 0x46: case 0x47:
|
|
case 0x48: case 0x49: case 0x4a: case 0x4b:
|
|
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
|
case 0x50: case 0x51: case 0x52: case 0x53:
|
|
case 0x54: case 0x55: case 0x56: case 0x57:
|
|
case 0x58: case 0x59: case 0x5a: case 0x5b:
|
|
case 0x5c: case 0x5d: case 0x5e: case 0x5f:
|
|
kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command);
|
|
dev->want60 = 1;
|
|
return 0;
|
|
|
|
case 0xa0: /* copyright message */
|
|
add_data(dev, 0x28);
|
|
add_data(dev, 0x00);
|
|
break;
|
|
|
|
case 0xa1: /* get controller version */
|
|
kbd_log("ATkbc: AMI - get controller version\n");
|
|
add_data(dev, 'H');
|
|
return 0;
|
|
|
|
case 0xa2: /* clear keyboard controller lines P22/P23 */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - clear KBC lines P22 and P23\n");
|
|
write_output(dev, dev->output_port & 0xf3);
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa3: /* set keyboard controller lines P22/P23 */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - set KBC lines P22 and P23\n");
|
|
write_output(dev, dev->output_port | 0x0c);
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa4: /* write clock = low */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - write clock = low\n");
|
|
dev->ami_stat &= 0xfe;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa5: /* write clock = high */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - write clock = high\n");
|
|
dev->ami_stat |= 0x01;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa6: /* read clock */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - read clock\n");
|
|
add_data(dev, !!(dev->ami_stat & 1));
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa7: /* write cache bad */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - write cache bad\n");
|
|
dev->ami_stat &= 0xfd;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa8: /* write cache good */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - write cache good\n");
|
|
dev->ami_stat |= 0x02;
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xa9: /* read cache */
|
|
if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) {
|
|
kbd_log("ATkbc: AMI - read cache\n");
|
|
add_data(dev, !!(dev->ami_stat & 2));
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case 0xaf: /* set extended controller RAM */
|
|
kbd_log("ATkbc: set extended controller RAM\n");
|
|
dev->want60 = 1;
|
|
dev->secr_phase = 1;
|
|
return 0;
|
|
|
|
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
|
|
/* set KBC lines P10-P13 (input port bits 0-3) low */
|
|
kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) low\n");
|
|
if (!PCI || (val > 0xb1))
|
|
dev->input_port &= ~(1 << (val & 0x03));
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xb4: case 0xb5:
|
|
/* set KBC lines P22-P23 (output port bits 2-3) low */
|
|
kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) low\n");
|
|
if (! PCI)
|
|
write_output(dev, dev->output_port & ~(4 << (val & 0x01)));
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xb8: case 0xb9: case 0xba: case 0xbb:
|
|
/* set KBC lines P10-P13 (input port bits 0-3) high */
|
|
kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) high\n");
|
|
if (!PCI || (val > 0xb9)) {
|
|
dev->input_port |= (1 << (val & 0x03));
|
|
add_data(dev, 0x00);
|
|
}
|
|
return 0;
|
|
|
|
case 0xbc: case 0xbd:
|
|
/* set KBC lines P22-P23 (output port bits 2-3) high */
|
|
kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) high\n");
|
|
if (! PCI)
|
|
write_output(dev, dev->output_port | (4 << (val & 0x01)));
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xc1: /* write input port */
|
|
kbd_log("ATkbc: AMI MegaKey - write input port\n");
|
|
dev->want60 = 1;
|
|
return 0;
|
|
|
|
case 0xc4:
|
|
/* set KBC line P14 low */
|
|
kbd_log("ATkbc: set KBC line P14 (input port bit 4) low\n");
|
|
dev->input_port &= 0xef;
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
case 0xc5:
|
|
/* set KBC line P15 low */
|
|
kbd_log("ATkbc: set KBC line P15 (input port bit 5) low\n");
|
|
dev->input_port &= 0xdf;
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xc8:
|
|
/*
|
|
* unblock KBC lines P22/P23
|
|
* (allow command D1 to change bits 2/3 of the output port)
|
|
*/
|
|
kbd_log("ATkbc: AMI - unblock KBC lines P22 and P23\n");
|
|
dev->output_locked = 1;
|
|
return 0;
|
|
|
|
case 0xc9:
|
|
/*
|
|
* block KBC lines P22/P23
|
|
* (disallow command D1 from changing bits 2/3 of the port)
|
|
*/
|
|
kbd_log("ATkbc: AMI - block KBC lines P22 and P23\n");
|
|
dev->output_locked = 1;
|
|
return 0;
|
|
|
|
case 0xcc:
|
|
/* set KBC line P14 high */
|
|
kbd_log("ATkbc: set KBC line P14 (input port bit 4) high\n");
|
|
dev->input_port |= 0x10;
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
case 0xcd:
|
|
/* set KBC line P15 high */
|
|
kbd_log("ATkbc: set KBC line P15 (input port bit 5) high\n");
|
|
dev->input_port |= 0x20;
|
|
add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xef: /* ??? - sent by AMI486 */
|
|
kbd_log("ATkbc: ??? - sent by AMI486\n");
|
|
return 0;
|
|
}
|
|
|
|
return write64_generic(dev, val);
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write64_ibm_mca(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch (val) {
|
|
case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/
|
|
kbd_log("ATkbc: copy bits 0 to 3 of input port to status bits 4 to 7\n");
|
|
dev->status &= 0x0f;
|
|
dev->status |= ((((dev->input_port & 0xfc) | 0x84) & 0x0f) << 4);
|
|
return 0;
|
|
|
|
case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/
|
|
kbd_log("ATkbc: copy bits 4 to 7 of input port to status bits 4 to 7\n");
|
|
dev->status &= 0x0f;
|
|
dev->status |= (((dev->input_port & 0xfc) | 0x84) & 0xf0);
|
|
return 0;
|
|
|
|
case 0xaf:
|
|
kbd_log("ATkbc: bad KBC command AF\n");
|
|
return 1;
|
|
|
|
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
|
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
|
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
|
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
|
kbd_log("ATkbc: pulse: %01X\n", (val & 0x03) | 0x0c);
|
|
pulse_output(dev, (val & 0x03) | 0x0c);
|
|
return 0;
|
|
}
|
|
|
|
return write64_generic(dev, val);
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write60_quadtel(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch(dev->command) {
|
|
case 0xcf: /*??? - sent by MegaPC BIOS*/
|
|
kbd_log("ATkbc: ??? - sent by MegaPC BIOS\n");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t
|
|
write64_olivetti(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch (val) {
|
|
case 0x80: /* Olivetti-specific command */
|
|
/*
|
|
* bit 7: bus expansion board present (M300) / keyboard unlocked (M290)
|
|
* bits 4-6: ???
|
|
* bit 3: fast ram check (if inactive keyboard works erratically)
|
|
* bit 2: keyboard fuse present
|
|
* bits 0-1: ???
|
|
*/
|
|
add_to_kbc_queue_front(dev, (0x0c | ((is386) ? 0x00 : 0x80)) & 0xdf, 0, 0x00);
|
|
dev->input_port = ((dev->input_port + 1) & 3) |
|
|
(dev->input_port & 0xfc);
|
|
return 0;
|
|
}
|
|
|
|
return write64_generic(dev, val);
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write64_quadtel(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch (val) {
|
|
case 0xaf:
|
|
kbd_log("ATkbc: bad KBC command AF\n");
|
|
return 1;
|
|
|
|
case 0xcf: /*??? - sent by MegaPC BIOS*/
|
|
kbd_log("ATkbc: ??? - sent by MegaPC BIOS\n");
|
|
dev->want60 = 1;
|
|
return 0;
|
|
}
|
|
|
|
return write64_generic(dev, val);
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write60_toshiba(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch(dev->command) {
|
|
case 0xb6: /* T3100e - set color/mono switch */
|
|
kbd_log("ATkbc: T3100e - set color/mono switch\n");
|
|
t3100e_mono_set(val);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
write64_toshiba(void *priv, uint8_t val)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
switch (val) {
|
|
case 0xaf:
|
|
kbd_log("ATkbc: bad KBC command AF\n");
|
|
return 1;
|
|
|
|
case 0xb0: /* T3100e: Turbo on */
|
|
kbd_log("ATkbc: T3100e: Turbo on\n");
|
|
t3100e_turbo_set(1);
|
|
return 0;
|
|
|
|
case 0xb1: /* T3100e: Turbo off */
|
|
kbd_log("ATkbc: T3100e: Turbo off\n");
|
|
t3100e_turbo_set(0);
|
|
return 0;
|
|
|
|
case 0xb2: /* T3100e: Select external display */
|
|
kbd_log("ATkbc: T3100e: Select external display\n");
|
|
t3100e_display_set(0x00);
|
|
return 0;
|
|
|
|
case 0xb3: /* T3100e: Select internal display */
|
|
kbd_log("ATkbc: T3100e: Select internal display\n");
|
|
t3100e_display_set(0x01);
|
|
return 0;
|
|
|
|
case 0xb4: /* T3100e: Get configuration / status */
|
|
kbd_log("ATkbc: T3100e: Get configuration / status\n");
|
|
add_data(dev, t3100e_config_get());
|
|
return 0;
|
|
|
|
case 0xb5: /* T3100e: Get colour / mono byte */
|
|
kbd_log("ATkbc: T3100e: Get colour / mono byte\n");
|
|
add_data(dev, t3100e_mono_get());
|
|
return 0;
|
|
|
|
case 0xb6: /* T3100e: Set colour / mono byte */
|
|
kbd_log("ATkbc: T3100e: Set colour / mono byte\n");
|
|
dev->want60 = 1;
|
|
return 0;
|
|
|
|
case 0xb7: /* T3100e: Emulate PS/2 keyboard */
|
|
case 0xb8: /* T3100e: Emulate AT keyboard */
|
|
dev->flags &= ~KBC_TYPE_MASK;
|
|
if (val == 0xb7) {
|
|
kbd_log("ATkbc: T3100e: Emulate PS/2 keyboard\n");
|
|
dev->flags |= KBC_TYPE_PS2_NOREF;
|
|
} else {
|
|
kbd_log("ATkbc: T3100e: Emulate AT keyboard\n");
|
|
dev->flags |= KBC_TYPE_ISA;
|
|
}
|
|
return 0;
|
|
|
|
case 0xbb: /* T3100e: Read 'Fn' key.
|
|
Return it for right Ctrl and right Alt; on the real
|
|
T3100e, these keystrokes could only be generated
|
|
using 'Fn'. */
|
|
kbd_log("ATkbc: T3100e: Read 'Fn' key\n");
|
|
if (keyboard_recv(0xb8) || /* Right Alt */
|
|
keyboard_recv(0x9d)) /* Right Ctrl */
|
|
add_data(dev, 0x04);
|
|
else add_data(dev, 0x00);
|
|
return 0;
|
|
|
|
case 0xbc: /* T3100e: Reset Fn+Key notification */
|
|
kbd_log("ATkbc: T3100e: Reset Fn+Key notification\n");
|
|
t3100e_notify_set(0x00);
|
|
return 0;
|
|
|
|
case 0xc0: /*Read input port*/
|
|
kbd_log("ATkbc: read input port\n");
|
|
|
|
/* The T3100e returns all bits set except bit 6 which
|
|
* is set by t3100e_mono_set() */
|
|
dev->input_port = (t3100e_mono_get() & 1) ? 0xff : 0xbf;
|
|
add_data(dev, dev->input_port);
|
|
return 0;
|
|
|
|
}
|
|
|
|
return write64_generic(dev, val);
|
|
}
|
|
|
|
|
|
static void
|
|
kbd_write(uint16_t port, uint8_t val, void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
int i = 0, bad = 1;
|
|
uint8_t mask, kbc_ven = 0x0;
|
|
kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
switch (port) {
|
|
case 0x60:
|
|
dev->status &= ~STAT_CD;
|
|
if (dev->want60) {
|
|
/* Write data to controller. */
|
|
dev->want60 = 0;
|
|
|
|
switch (dev->command) {
|
|
case 0x60: case 0x61: case 0x62: case 0x63:
|
|
case 0x64: case 0x65: case 0x66: case 0x67:
|
|
case 0x68: case 0x69: case 0x6a: case 0x6b:
|
|
case 0x6c: case 0x6d: case 0x6e: case 0x6f:
|
|
case 0x70: case 0x71: case 0x72: case 0x73:
|
|
case 0x74: case 0x75: case 0x76: case 0x77:
|
|
case 0x78: case 0x79: case 0x7a: case 0x7b:
|
|
case 0x7c: case 0x7d: case 0x7e: case 0x7f:
|
|
dev->mem[dev->command & 0x1f] = val;
|
|
if (dev->command == 0x60)
|
|
write_cmd(dev, val);
|
|
break;
|
|
|
|
case 0xd1: /* write output port */
|
|
kbd_log("ATkbc: write output port\n");
|
|
if (dev->output_locked) {
|
|
/*If keyboard controller lines P22-P23 are blocked,
|
|
we force them to remain unchanged.*/
|
|
val &= ~0x0c;
|
|
val |= (dev->output_port & 0x0c);
|
|
}
|
|
write_output(dev, val);
|
|
break;
|
|
|
|
case 0xd2: /* write to keyboard output buffer */
|
|
kbd_log("ATkbc: write to keyboard output buffer\n");
|
|
add_to_kbc_queue_front(dev, val, 0, 0x00);
|
|
break;
|
|
|
|
case 0xd3: /* write to mouse output buffer */
|
|
kbd_log("ATkbc: write to mouse output buffer\n");
|
|
if (mouse_write && ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF))
|
|
keyboard_at_adddata_mouse(val);
|
|
break;
|
|
|
|
case 0xd4: /* write to mouse */
|
|
kbd_log("ATkbc: write to mouse (%02X)\n", val);
|
|
|
|
if (val == 0xbb)
|
|
break;
|
|
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) {
|
|
set_enable_mouse(dev, 1);
|
|
if (mouse_write)
|
|
mouse_write(val, mouse_p);
|
|
else
|
|
add_to_kbc_queue_front(dev, 0xfe, 2, 0x40);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* Run the vendor-specific handler
|
|
* if we have one. Otherwise, or if
|
|
* it returns an error, log a bad
|
|
* controller command.
|
|
*/
|
|
if (dev->write60_ven)
|
|
bad = dev->write60_ven(dev, val);
|
|
|
|
if (bad) {
|
|
kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, val);
|
|
add_data_kbd(0xfe);
|
|
}
|
|
}
|
|
} else {
|
|
/* Write data to keyboard. */
|
|
dev->mem[0] &= ~0x10;
|
|
|
|
if (dev->key_wantdata) {
|
|
dev->key_wantdata = 0;
|
|
|
|
/*
|
|
* Several system BIOSes and OS device drivers
|
|
* mess up with this, and repeat the command
|
|
* code many times. Fun!
|
|
*/
|
|
if (val == dev->key_command) {
|
|
/* Respond NAK and ignore it. */
|
|
add_data_kbd(0xfe);
|
|
dev->key_command = 0x00;
|
|
break;
|
|
}
|
|
|
|
switch (dev->key_command) {
|
|
case 0xed: /* set/reset LEDs */
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
kbd_log("ATkbd: set LEDs [%02x]\n", val);
|
|
break;
|
|
|
|
case 0xf0: /* get/set scancode set */
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
if (val == 0) {
|
|
kbd_log("Get scan code set: %02X\n", keyboard_mode & 3);
|
|
add_data_kbd_direct(dev, keyboard_mode & 3);
|
|
} else {
|
|
if ((val <= 3) && (val != 1)) {
|
|
keyboard_mode &= 0xfc;
|
|
keyboard_mode |= (val & 3);
|
|
kbd_log("Scan code set now: %02X\n", val);
|
|
}
|
|
set_scancode_map(dev);
|
|
}
|
|
break;
|
|
|
|
case 0xf3: /* set typematic rate/delay */
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
break;
|
|
|
|
default:
|
|
kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, dev->key_command);
|
|
add_data_kbd_direct(dev, 0xfe);
|
|
break;
|
|
}
|
|
|
|
/* Keyboard command is now done. */
|
|
dev->key_command = 0x00;
|
|
} else {
|
|
/* No keyboard command in progress. */
|
|
dev->key_command = 0x00;
|
|
|
|
set_enable_kbd(dev, 1);
|
|
|
|
switch (val) {
|
|
case 0x00:
|
|
kbd_log("ATkbd: command 00\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
break;
|
|
|
|
case 0x05: /*??? - sent by NT 4.0*/
|
|
kbd_log("ATkbd: command 05 (NT 4.0)\n");
|
|
add_data_kbd_direct(dev, 0xfe);
|
|
break;
|
|
|
|
/* Sent by Pentium-era AMI BIOS'es.*/
|
|
case 0x71: case 0x82:
|
|
kbd_log("ATkbd: Pentium-era AMI BIOS command %02X\n", val);
|
|
break;
|
|
|
|
case 0xed: /* set/reset LEDs */
|
|
kbd_log("ATkbd: set/reset leds\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
|
|
dev->key_wantdata = 1;
|
|
break;
|
|
|
|
case 0xee: /* diagnostic echo */
|
|
kbd_log("ATkbd: ECHO\n");
|
|
add_data_kbd_direct(dev, 0xee);
|
|
break;
|
|
|
|
case 0xef: /* NOP (reserved for future use) */
|
|
kbd_log("ATkbd: NOP\n");
|
|
break;
|
|
|
|
case 0xf0: /* get/set scan code set */
|
|
kbd_log("ATkbd: scan code set\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
dev->key_wantdata = 1;
|
|
break;
|
|
|
|
case 0xf2: /* read ID */
|
|
/* Fixed as translation will be done in add_data_kbd(). */
|
|
kbd_log("ATkbd: read keyboard id\n");
|
|
/* TODO: After keyboard type selection is implemented, make this
|
|
return the correct keyboard ID for the selected type. */
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
add_data_kbd_direct(dev, 0xab);
|
|
add_data_kbd_direct(dev, 0x83);
|
|
break;
|
|
|
|
case 0xf3: /* set typematic rate/delay */
|
|
kbd_log("ATkbd: set typematic rate/delay\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
dev->key_wantdata = 1;
|
|
break;
|
|
|
|
case 0xf4: /* enable keyboard */
|
|
kbd_log("ATkbd: enable keyboard\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
keyboard_scan = 1;
|
|
break;
|
|
|
|
case 0xf5: /* set defaults and disable keyboard */
|
|
case 0xf6: /* set defaults */
|
|
kbd_log("ATkbd: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard");
|
|
keyboard_scan = (val == 0xf6);
|
|
kbd_log("val = %02X, keyboard_scan = %i, dev->mem[0] = %02X\n",
|
|
val, keyboard_scan, dev->mem[0]);
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
|
|
keyboard_set3_all_break = 0;
|
|
keyboard_set3_all_repeat = 0;
|
|
memset(keyboard_set3_flags, 0, 512);
|
|
keyboard_mode = (keyboard_mode & 0xfc) | 0x02;
|
|
set_scancode_map(dev);
|
|
break;
|
|
|
|
case 0xf7: /* set all keys to repeat */
|
|
kbd_log("ATkbd: set all keys to repeat\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
keyboard_set3_all_break = 1;
|
|
break;
|
|
|
|
case 0xf8: /* set all keys to give make/break codes */
|
|
kbd_log("ATkbd: set all keys to give make/break codes\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
keyboard_set3_all_break = 1;
|
|
break;
|
|
|
|
case 0xf9: /* set all keys to give make codes only */
|
|
kbd_log("ATkbd: set all keys to give make codes only\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
keyboard_set3_all_break = 0;
|
|
break;
|
|
|
|
case 0xfa: /* set all keys to repeat and give make/break codes */
|
|
kbd_log("ATkbd: set all keys to repeat and give make/break codes\n");
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
keyboard_set3_all_repeat = 1;
|
|
keyboard_set3_all_break = 1;
|
|
break;
|
|
|
|
case 0xfe: /* resend last scan code */
|
|
kbd_log("ATkbd: reset last scan code\n");
|
|
add_data_kbd_raw(dev, kbd_last_scan_code);
|
|
break;
|
|
|
|
case 0xff: /* reset */
|
|
kbd_log("ATkbd: kbd reset\n");
|
|
kbc_queue_reset(1);
|
|
kbd_last_scan_code = 0x00;
|
|
add_data_kbd_direct(dev, 0xfa);
|
|
|
|
/* Set scan code set to 2. */
|
|
keyboard_mode = (keyboard_mode & 0xfc) | 0x02;
|
|
set_scancode_map(dev);
|
|
|
|
dev->reset_delay = RESET_DELAY_TIME;
|
|
break;
|
|
|
|
default:
|
|
kbd_log("ATkbd: bad keyboard command %02X\n", val);
|
|
add_data_kbd_direct(dev, 0xfe);
|
|
}
|
|
|
|
/* If command needs data, remember command. */
|
|
if (dev->key_wantdata == 1)
|
|
dev->key_command = val;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0x64:
|
|
/* Controller command. */
|
|
dev->want60 = 0;
|
|
dev->status |= STAT_CD;
|
|
|
|
switch (val) {
|
|
/* Read data from KBC memory. */
|
|
case 0x20: case 0x21: case 0x22: case 0x23:
|
|
case 0x24: case 0x25: case 0x26: case 0x27:
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b:
|
|
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
case 0x30: case 0x31: case 0x32: case 0x33:
|
|
case 0x34: case 0x35: case 0x36: case 0x37:
|
|
case 0x38: case 0x39: case 0x3a: case 0x3b:
|
|
case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
|
add_data(dev, dev->mem[val & 0x1f]);
|
|
break;
|
|
|
|
/* Write data to KBC memory. */
|
|
case 0x60: case 0x61: case 0x62: case 0x63:
|
|
case 0x64: case 0x65: case 0x66: case 0x67:
|
|
case 0x68: case 0x69: case 0x6a: case 0x6b:
|
|
case 0x6c: case 0x6d: case 0x6e: case 0x6f:
|
|
case 0x70: case 0x71: case 0x72: case 0x73:
|
|
case 0x74: case 0x75: case 0x76: case 0x77:
|
|
case 0x78: case 0x79: case 0x7a: case 0x7b:
|
|
case 0x7c: case 0x7d: case 0x7e: case 0x7f:
|
|
dev->want60 = 1;
|
|
break;
|
|
|
|
case 0xaa: /* self-test */
|
|
kbd_log("ATkbc: self-test\n");
|
|
if ((kbc_ven == KBC_VEN_TOSHIBA) || (kbc_ven == KBC_VEN_SAMSUNG))
|
|
dev->status |= STAT_IFULL;
|
|
write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf);
|
|
|
|
/* Always reinitialize all queues - the real hardware pulls keyboard and mouse
|
|
clocks high, which stops keyboard scanning. */
|
|
kbd_log("ATkbc: self-test reinitialization\n");
|
|
dev->out_new = dev->out_delayed = -1;
|
|
for (i = 0; i < 3; i++)
|
|
kbc_queue_reset(i);
|
|
kbd_last_scan_code = 0x00;
|
|
dev->status &= ~STAT_OFULL;
|
|
dev->last_irq = dev->old_last_irq = 0;
|
|
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)
|
|
write_cmd(dev, 0x30 | STAT_SYSFLAG);
|
|
else
|
|
write_cmd(dev, 0x10 | STAT_SYSFLAG);
|
|
add_data(dev, 0x55);
|
|
break;
|
|
|
|
case 0xab: /* interface test */
|
|
kbd_log("ATkbc: interface test\n");
|
|
add_data(dev, 0x00); /*no error*/
|
|
break;
|
|
|
|
case 0xac: /* diagnostic dump */
|
|
kbd_log("ATkbc: diagnostic dump\n");
|
|
for (i = 0; i < 16; i++)
|
|
add_data(dev, dev->mem[i]);
|
|
add_data(dev, (dev->input_port & 0xf0) | 0x80);
|
|
add_data(dev, dev->output_port);
|
|
add_data(dev, dev->status);
|
|
break;
|
|
|
|
case 0xad: /* disable keyboard */
|
|
kbd_log("ATkbc: disable keyboard\n");
|
|
set_enable_kbd(dev, 0);
|
|
break;
|
|
|
|
case 0xae: /* enable keyboard */
|
|
kbd_log("ATkbc: enable keyboard\n");
|
|
set_enable_kbd(dev, 1);
|
|
break;
|
|
|
|
case 0xca: /* read keyboard mode */
|
|
kbd_log("ATkbc: AMI - read keyboard mode\n");
|
|
add_data(dev, dev->ami_flags);
|
|
break;
|
|
|
|
case 0xcb: /* set keyboard mode */
|
|
kbd_log("ATkbc: AMI - set keyboard mode\n");
|
|
dev->want60 = 1;
|
|
break;
|
|
|
|
case 0xd0: /* read output port */
|
|
kbd_log("ATkbc: read output port\n");
|
|
mask = 0xff;
|
|
if ((kbc_ven != KBC_VEN_OLIVETTI) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) && (dev->mem[0] & 0x10))
|
|
mask &= 0xbf;
|
|
add_to_kbc_queue_front(dev, dev->output_port & mask, 0, 0x00);
|
|
break;
|
|
|
|
case 0xd1: /* write output port */
|
|
kbd_log("ATkbc: write output port\n");
|
|
dev->want60 = 1;
|
|
break;
|
|
|
|
case 0xd2: /* write keyboard output buffer */
|
|
kbd_log("ATkbc: write keyboard output buffer\n");
|
|
dev->want60 = 1;
|
|
break;
|
|
|
|
case 0xdd: /* disable A20 address line */
|
|
case 0xdf: /* enable A20 address line */
|
|
kbd_log("ATkbc: %sable A20\n", (val == 0xdd) ? "dis": "en");
|
|
write_output(dev, (dev->output_port & 0xfd) | (val & 0x02));
|
|
break;
|
|
|
|
case 0xe0: /* read test inputs */
|
|
kbd_log("ATkbc: read test inputs\n");
|
|
add_data(dev, 0x00);
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* Unrecognized controller command.
|
|
*
|
|
* If we have a vendor-specific handler, run
|
|
* that. Otherwise, or if that handler fails,
|
|
* log a bad command.
|
|
*/
|
|
if (dev->write64_ven)
|
|
bad = dev->write64_ven(dev, val);
|
|
|
|
kbd_log(bad ? "ATkbc: bad controller command %02X\n" : "", val);
|
|
}
|
|
|
|
/* If the command needs data, remember the command. */
|
|
if (dev->want60)
|
|
dev->command = val;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static uint8_t
|
|
kbd_read(uint16_t port, void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
uint8_t ret = 0xff;
|
|
uint8_t kbc_ven = 0x0;
|
|
kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)
|
|
cycles -= ISA_CYCLES(8);
|
|
|
|
switch (port) {
|
|
case 0x60:
|
|
ret = dev->out;
|
|
dev->status &= ~STAT_OFULL;
|
|
picintc(dev->last_irq);
|
|
dev->last_irq = 0;
|
|
break;
|
|
|
|
case 0x64:
|
|
ret = (dev->status & 0xfb);
|
|
if (dev->mem[0] & STAT_SYSFLAG)
|
|
ret |= STAT_SYSFLAG;
|
|
/* Only clear the transmit timeout flag on non-PS/2 controllers, as on
|
|
PS/2 controller, it is the keyboard/mouse output source bit. */
|
|
// dev->status &= ~STAT_RTIMEOUT;
|
|
if (((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) &&
|
|
(kbc_ven != KBC_VEN_IBM_MCA))
|
|
dev->status &= ~STAT_TTIMEOUT;
|
|
break;
|
|
|
|
default:
|
|
kbd_log("ATkbc: read(%04x) invalid!\n", port);
|
|
break;
|
|
}
|
|
|
|
kbd_log((port == 0x61) ? "" : "ATkbc: read(%04X) = %02X\n", port, ret);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
|
|
static void
|
|
kbd_reset(void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
int i;
|
|
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
|
|
|
dev->first_write = 1;
|
|
// dev->status = STAT_UNLOCKED | STAT_CD;
|
|
dev->status = STAT_UNLOCKED;
|
|
dev->mem[0] = 0x01;
|
|
dev->mem[0] |= CCB_TRANSLATE;
|
|
dev->wantirq = 0;
|
|
write_output(dev, 0xcf);
|
|
dev->last_irq = dev->old_last_irq = 0;
|
|
dev->secr_phase = 0;
|
|
dev->key_wantdata = 0;
|
|
|
|
/* Set up the correct Video Type bits. */
|
|
if ((kbc_ven == KBC_VEN_XI8088) || (kbc_ven == KBC_VEN_ACER))
|
|
dev->input_port = video_is_mda() ? 0xb0 : 0xf0;
|
|
else
|
|
dev->input_port = video_is_mda() ? 0xf0 : 0xb0;
|
|
kbd_log("ATkbc: input port = %02x\n", dev->input_port);
|
|
|
|
keyboard_mode = 0x02 | (dev->mem[0] & CCB_TRANSLATE);
|
|
|
|
/* Enable keyboard, disable mouse. */
|
|
set_enable_kbd(dev, 1);
|
|
keyboard_scan = 1;
|
|
set_enable_mouse(dev, 0);
|
|
mouse_scan = 0;
|
|
|
|
dev->out_new = dev->out_delayed = -1;
|
|
for (i = 0; i < 3; i++)
|
|
kbc_queue_reset(i);
|
|
kbd_last_scan_code = 0;
|
|
|
|
sc_or = 0;
|
|
|
|
memset(keyboard_set3_flags, 0, 512);
|
|
|
|
set_scancode_map(dev);
|
|
|
|
dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00;
|
|
}
|
|
|
|
|
|
/* Reset the AT keyboard - this is needed for the PCI TRC and is done
|
|
until a better solution is found. */
|
|
void
|
|
keyboard_at_reset(void)
|
|
{
|
|
kbd_reset(SavedKbd);
|
|
}
|
|
|
|
|
|
static void
|
|
kbd_close(void *priv)
|
|
{
|
|
atkbd_t *dev = (atkbd_t *)priv;
|
|
|
|
kbd_reset(dev);
|
|
|
|
/* Stop timers. */
|
|
timer_disable(&dev->send_delay_timer);
|
|
|
|
keyboard_scan = 0;
|
|
keyboard_send = NULL;
|
|
|
|
/* Disable the scancode maps. */
|
|
keyboard_set_table(NULL);
|
|
|
|
SavedKbd = NULL;
|
|
free(dev);
|
|
}
|
|
|
|
|
|
static void *
|
|
kbd_init(const device_t *info)
|
|
{
|
|
atkbd_t *dev;
|
|
|
|
dev = (atkbd_t *)malloc(sizeof(atkbd_t));
|
|
memset(dev, 0x00, sizeof(atkbd_t));
|
|
|
|
dev->flags = info->local;
|
|
|
|
video_reset(gfxcard);
|
|
kbd_reset(dev);
|
|
|
|
io_sethandler(0x0060, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev);
|
|
io_sethandler(0x0064, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev);
|
|
keyboard_send = add_data_kbd;
|
|
|
|
timer_add(&dev->send_delay_timer, kbd_poll, dev, 1);
|
|
timer_add(&dev->pulse_cb, pulse_poll, dev, 0);
|
|
|
|
dev->write60_ven = NULL;
|
|
dev->write64_ven = NULL;
|
|
|
|
switch(dev->flags & KBC_VEN_MASK) {
|
|
case KBC_VEN_ACER:
|
|
case KBC_VEN_GENERIC:
|
|
case KBC_VEN_NCR:
|
|
case KBC_VEN_IBM_PS1:
|
|
case KBC_VEN_XI8088:
|
|
dev->write64_ven = write64_generic;
|
|
break;
|
|
|
|
case KBC_VEN_OLIVETTI:
|
|
dev->write64_ven = write64_olivetti;
|
|
break;
|
|
|
|
case KBC_VEN_AMI:
|
|
case KBC_VEN_INTEL_AMI:
|
|
case KBC_VEN_SAMSUNG:
|
|
dev->write60_ven = write60_ami;
|
|
dev->write64_ven = write64_ami;
|
|
break;
|
|
|
|
case KBC_VEN_IBM_MCA:
|
|
dev->write64_ven = write64_ibm_mca;
|
|
break;
|
|
|
|
case KBC_VEN_QUADTEL:
|
|
dev->write60_ven = write60_quadtel;
|
|
dev->write64_ven = write64_quadtel;
|
|
break;
|
|
|
|
case KBC_VEN_TOSHIBA:
|
|
dev->write60_ven = write60_toshiba;
|
|
dev->write64_ven = write64_toshiba;
|
|
break;
|
|
}
|
|
|
|
/* We need this, sadly. */
|
|
SavedKbd = dev;
|
|
|
|
return(dev);
|
|
}
|
|
|
|
|
|
const device_t keyboard_at_device = {
|
|
"PC/AT Keyboard",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_GENERIC,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_at_ami_device = {
|
|
"PC/AT Keyboard (AMI)",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_AMI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_at_samsung_device = {
|
|
"PC/AT Keyboard (Samsung)",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_SAMSUNG,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_at_toshiba_device = {
|
|
"PC/AT Keyboard (Toshiba)",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_TOSHIBA,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_at_olivetti_device = {
|
|
"PC/AT Keyboard (Olivetti)",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_OLIVETTI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_at_ncr_device = {
|
|
"PC/AT Keyboard (NCR)",
|
|
0,
|
|
KBC_TYPE_ISA | KBC_VEN_NCR,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_device = {
|
|
"PS/2 Keyboard",
|
|
0,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_ps2_device = {
|
|
"PS/2 Keyboard",
|
|
0,
|
|
KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_ps1_device = {
|
|
"PS/2 Keyboard (IBM PS/1)",
|
|
0,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_ps1_pci_device = {
|
|
"PS/2 Keyboard (IBM PS/1)",
|
|
DEVICE_PCI,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_xi8088_device = {
|
|
"PS/2 Keyboard (Xi8088)",
|
|
0,
|
|
KBC_TYPE_PS2_1 | KBC_VEN_XI8088,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_ami_device = {
|
|
"PS/2 Keyboard (AMI)",
|
|
0,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_AMI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_olivetti_device = {
|
|
"PS/2 Keyboard (Olivetti)",
|
|
0,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_OLIVETTI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_mca_device = {
|
|
"PS/2 Keyboard",
|
|
0,
|
|
KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_mca_2_device = {
|
|
"PS/2 Keyboard",
|
|
0,
|
|
KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_quadtel_device = {
|
|
"PS/2 Keyboard (Quadtel/MegaPC)",
|
|
0,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_QUADTEL,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_pci_device = {
|
|
"PS/2 Keyboard",
|
|
DEVICE_PCI,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_ami_pci_device = {
|
|
"PS/2 Keyboard (AMI)",
|
|
DEVICE_PCI,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_AMI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_intel_ami_pci_device = {
|
|
"PS/2 Keyboard (AMI)",
|
|
DEVICE_PCI,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_INTEL_AMI,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
const device_t keyboard_ps2_acer_pci_device = {
|
|
"PS/2 Keyboard (Acer 90M002A)",
|
|
DEVICE_PCI,
|
|
KBC_TYPE_PS2_NOREF | KBC_VEN_ACER,
|
|
kbd_init,
|
|
kbd_close,
|
|
kbd_reset,
|
|
{ NULL }, NULL, NULL, NULL
|
|
};
|
|
|
|
|
|
void
|
|
keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv)
|
|
{
|
|
mouse_write = func;
|
|
mouse_p = priv;
|
|
}
|
|
|
|
|
|
void
|
|
keyboard_at_adddata_keyboard_raw(uint8_t val)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
|
|
add_data_kbd_queue(dev, 0, val);
|
|
}
|
|
|
|
|
|
void
|
|
keyboard_at_adddata_mouse(uint8_t val)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
|
|
kbc_queue_add(dev, val, 2, 0x00);
|
|
}
|
|
|
|
|
|
void
|
|
keyboard_at_mouse_reset(void)
|
|
{
|
|
kbc_queue_reset(2);
|
|
}
|
|
|
|
|
|
uint8_t
|
|
keyboard_at_mouse_pos(void)
|
|
{
|
|
return ((mouse_queue_end - mouse_queue_start) & 0xf);
|
|
}
|
|
|
|
|
|
void
|
|
keyboard_at_set_mouse_scan(uint8_t val)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
uint8_t temp_mouse_scan = val ? 1 : 0;
|
|
|
|
if (temp_mouse_scan == !(dev->mem[0] & 0x20))
|
|
return;
|
|
|
|
set_enable_mouse(dev, val ? 1 : 0);
|
|
|
|
kbd_log("ATkbc: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis");
|
|
}
|
|
|
|
|
|
uint8_t
|
|
keyboard_at_get_mouse_scan(void)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
|
|
return((dev->mem[0] & 0x20) ? 0x00 : 0x10);
|
|
}
|
|
|
|
|
|
void
|
|
keyboard_at_set_a20_key(int state)
|
|
{
|
|
atkbd_t *dev = SavedKbd;
|
|
|
|
write_output(dev, (dev->output_port & 0xfd) | ((!!state) << 1));
|
|
}
|