From 69f76176fe522353727167d9f172a97db1c5294c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 May 2023 03:30:42 +0200 Subject: [PATCH] Removed unncessary files. --- src/device/keyboard_at - Cópia.c | 3258 ------------------------------ src/device/mouse_ps2 - Cópia.c | 404 ---- src/mem/mem - Cópia.c | 3092 ---------------------------- src/mouse.patch | 69 - src/pic - Cópia.c | 838 -------- 5 files changed, 7661 deletions(-) delete mode 100644 src/device/keyboard_at - Cópia.c delete mode 100644 src/device/mouse_ps2 - Cópia.c delete mode 100644 src/mem/mem - Cópia.c delete mode 100644 src/mouse.patch delete mode 100644 src/pic - Cópia.c diff --git a/src/device/keyboard_at - Cópia.c b/src/device/keyboard_at - Cópia.c deleted file mode 100644 index 3a841ad91..000000000 --- a/src/device/keyboard_at - Cópia.c +++ /dev/null @@ -1,3258 +0,0 @@ -/* - * 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, - * Miran Grca, - * Fred N. van Kempen, - * EngiNerd, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2020 EngiNerd. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#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_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 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_IBM_PS1 0x14 -#define KBC_VEN_ACER 0x18 -#define KBC_VEN_INTEL_AMI 0x1c -#define KBC_VEN_OLIVETTI 0x20 -#define KBC_VEN_NCR 0x24 -#define KBC_VEN_PHOENIX 0x28 -#define KBC_VEN_ALI 0x2c -#define KBC_VEN_TG 0x30 -#define KBC_VEN_TG_GREEN 0x34 -#define KBC_VEN_MASK 0x3c - -enum { - KBC_STATE_RESET = 0, - KBC_STATE_MAIN_IBF, - KBC_STATE_MAIN_KBD, - KBC_STATE_MAIN_MOUSE, - KBC_STATE_MAIN_BOTH, - KBC_STATE_KBC_OUT, - KBC_STATE_KBC_PARAM, - KBC_STATE_SEND_KBD, - KBC_STATE_KBD, - KBC_STATE_SEND_MOUSE, - KBC_STATE_MOUSE -}; -#define KBC_STATE_SCAN_KBD KBC_STATE_KBD -#define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE - -enum { - DEV_STATE_MAIN_1 = 0, - DEV_STATE_MAIN_2, - DEV_STATE_MAIN_CMD, - DEV_STATE_MAIN_OUT, - DEV_STATE_MAIN_WANT_IN, - DEV_STATE_MAIN_IN -}; - -typedef struct { - /* Controller. */ - uint8_t pci, kbc_state, command, want60, - status, ib, out, old_out, - sc_or, secr_phase, mem_addr, input_port, - output_port, old_output_port, output_locked, ami_stat, - ami_flags, key_ctrl_queue_start, key_ctrl_queue_end; - - /* Keyboard. */ - uint8_t key_command, key_wantdata, kbd_last_scan_code, - kbd_state, key_wantcmd, key_dat, key_cmd_queue_start, - key_cmd_queue_end, key_queue_start, key_queue_end; - - /* Mouse. */ - uint8_t mouse_state, mouse_wantcmd, mouse_dat, mouse_cmd_queue_start, - mouse_cmd_queue_end, mouse_queue_start, mouse_queue_end; - - /* Controller. */ - uint8_t mem[0x100]; - - /* Controller - internal FIFO for the purpose of commands with multi-byte output. */ - uint8_t key_ctrl_queue[64]; - - /* Keyboard - command response FIFO. */ - uint8_t key_cmd_queue[16]; - - /* Keyboard - scan FIFO. */ - uint8_t key_queue[16]; - - /* Mouse - command response FIFO. */ - uint8_t mouse_cmd_queue[16]; - - /* Mouse - scan FIFO. */ - uint8_t mouse_queue[16]; - - /* Keyboard. */ - int out_new; - - /* Mouse. */ - int out_new_mouse; - - /* Controller. */ - uint32_t flags; - - /* Controller (main timer). */ - pc_timer_t send_delay_timer; - - /* Controller (P2 pulse callback timer). */ - pc_timer_t pulse_cb; - - uint8_t (*write60_ven)(void *p, uint8_t val); - uint8_t (*write64_ven)(void *p, uint8_t val); -} atkbd_t; - -/* Global keyboard flags for scan code set 3: - 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; - -/* Global keyboard mode: - Bits 0 - 1 = scan code set. */ -uint8_t keyboard_mode = 0x02; - -/* Keyboard controller ports. */ -kbc_port_t *kbc_ports[2] = { NULL, NULL }; - -static void (*mouse_write)(uint8_t val, void *priv) = NULL; -static void *mouse_p = NULL; -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 -}; - -static const scancode scancode_set1[512] = { - // clang-format off - { { 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*/ - // clang-format on -}; - -static const scancode scancode_set2[512] = { - // clang-format off - { { 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*/ - // clang-format on -}; - -static const scancode scancode_set3[512] = { - // clang-format off - { { 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*/ - // clang-format on -}; - -// #define ENABLE_KEYBOARD_AT_LOG 1 -#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) { - case 1: - default: - keyboard_set_table(scancode_set1); - break; - case 2: - keyboard_set_table(scancode_set2); - break; - - case 3: - keyboard_set_table(scancode_set3); - break; - } -} - -static void -kbc_queue_reset(atkbd_t *dev, uint8_t channel) -{ - switch (channel) { - case 1: - dev->key_queue_start = dev->key_queue_end = 0; - memset(dev->key_queue, 0x00, sizeof(dev->key_queue)); - /* FALLTHROUGH */ - case 4: - dev->key_cmd_queue_start = dev->key_cmd_queue_end = 0; - memset(dev->key_cmd_queue, 0x00, sizeof(dev->key_cmd_queue)); - break; - - case 2: - dev->mouse_queue_start = dev->mouse_queue_end = 0; - memset(dev->mouse_queue, 0x00, sizeof(dev->mouse_queue)); - /* FALLTHROUGH */ - case 3: - dev->mouse_cmd_queue_start = dev->mouse_cmd_queue_end = 0; - memset(dev->mouse_cmd_queue, 0x00, sizeof(dev->mouse_cmd_queue)); - break; - - case 0: - default: - dev->key_ctrl_queue_start = dev->key_ctrl_queue_end = 0; - memset(dev->key_ctrl_queue, 0x00, sizeof(dev->key_ctrl_queue)); - } -} - -static void -kbc_queue_add(atkbd_t *dev, uint8_t val, uint8_t channel) -{ - switch (channel) { - case 4: - kbd_log("ATkbc: dev->key_cmd_queue[%02X] = %02X;\n", dev->key_cmd_queue_end, val); - dev->key_cmd_queue[dev->key_cmd_queue_end] = val; - dev->key_cmd_queue_end = (dev->key_cmd_queue_end + 1) & 0xf; - break; - case 3: - kbd_log("ATkbc: dev->mouse_cmd_queue[%02X] = %02X;\n", dev->mouse_cmd_queue_end, val); - dev->mouse_cmd_queue[dev->mouse_cmd_queue_end] = val; - dev->mouse_cmd_queue_end = (dev->mouse_cmd_queue_end + 1) & 0xf; - break; - case 2: - kbd_log("ATkbc: dev->mouse_queue[%02X] = %02X;\n", dev->mouse_queue_end, val); - dev->mouse_queue[dev->mouse_queue_end] = val; - dev->mouse_queue_end = (dev->mouse_queue_end + 1) & 0xf; - break; - case 1: - kbd_log("ATkbc: dev->key_queue[%02X] = %02X;\n", dev->key_queue_end, val); - dev->key_queue[dev->key_queue_end] = val; - dev->key_queue_end = (dev->key_queue_end + 1) & 0xf; - break; - case 0: - default: - kbd_log("ATkbc: dev->key_ctrl_queue[%02X] = %02X;\n", dev->key_ctrl_queue_end, val); - dev->key_ctrl_queue[dev->key_ctrl_queue_end] = val; - dev->key_ctrl_queue_end = (dev->key_ctrl_queue_end + 1) & 0x3f; - break; - } -} - -static int -kbc_translate(atkbd_t *dev, uint8_t val) -{ - int xt_mode = (dev->mem[0x20] & 0x20) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF); - int translate = (dev->mem[0x20] & 0x40) || xt_mode || ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2); - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - int ret = - 1; - - /* Allow for scan code translation. */ - if (translate && (val == 0xf0)) { - kbd_log("ATkbd: translate is on, F0 prefix detected\n"); - dev->sc_or = 0x80; - return ret; - } - - /* Skip break code if translated make code has bit 7 set. */ - if (translate && (dev->sc_or == 0x80) && (nont_to_t[val] & 0x80)) { - kbd_log("ATkbd: translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); - dev->sc_or = 0; - return ret; - } - - /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) && - (keyboard_recv(0x138) || keyboard_recv(0x11d))) 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"); -#ifdef ENABLE_KEYBOARD_AT_LOG - kbd_log("scan code: "); - if (translate) { - kbd_log("%02X (original: ", (nont_to_t[val] | dev->sc_or)); - if (dev->sc_or == 0x80) - kbd_log("F0 "); - kbd_log("%02X)\n", val); - } else - kbd_log("%02X\n", val); -#endif - - ret = translate ? (nont_to_t[val] | dev->sc_or) : val; - - if (dev->sc_or == 0x80) - dev->sc_or = 0; - - return ret; -} - -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; - int temp = (channel == 1) ? kbc_translate(dev, val) : val; - - if (temp == -1) - return; - - if ((kbc_ven == KBC_VEN_AMI) || (kbc_ven == KBC_VEN_TG) || - (kbc_ven == KBC_VEN_TG_GREEN) || ((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 on channel %i...\n", temp, channel); - dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi; - - /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly - written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - if (channel >= 2) { - dev->status |= STAT_MFULL; - - if (dev->mem[0x20] & 0x02) - picint_common(1 << 12, 0, 1); - picint_common(1 << 1, 0, 0); - } else { - if (dev->mem[0x20] & 0x01) - picint_common(1 << 1, 0, 1); - picint_common(1 << 12, 0, 0); - } - } else if (dev->mem[0x20] & 0x01) - picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ - - dev->out = temp; -} - -static void -add_data_kbd_cmd_queue(atkbd_t *dev, uint8_t val) -{ - if (dev->key_cmd_queue_end >= 16) { - kbd_log("ATkbc: Unable to add to queue, dev->key_cmd_queue_end >= 16\n"); - return; - } - kbd_log("ATkbc: dev->key_cmd_queue[%02X] = %02X;\n", dev->key_cmd_queue_end, val); - kbc_queue_add(dev, val, 4); - dev->kbd_last_scan_code = val; -} - -static void -add_data_kbd_queue(atkbd_t *dev, uint8_t val) -{ - if (!keyboard_scan || (dev->key_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", !keyboard_scan, (dev->key_queue_end >= 16)); - return; - } - kbd_log("ATkbc: key_queue[%02X] = %02X;\n", dev->key_queue_end, val); - kbc_queue_add(dev, val, 1); - dev->kbd_last_scan_code = val; -} - -static void -add_data_kbd_front(atkbd_t *dev, uint8_t val) -{ - add_data_kbd_cmd_queue(dev, val); -} - -static void kbd_process_cmd(void *priv); -static void kbc_process_cmd(void *priv); - -static void -set_enable_kbd(atkbd_t *dev, uint8_t enable) -{ - dev->mem[0x20] &= 0xef; - dev->mem[0x20] |= (enable ? 0x00 : 0x10); -} - -static void -set_enable_mouse(atkbd_t *dev, uint8_t enable) -{ - dev->mem[0x20] &= 0xdf; - dev->mem[0x20] |= (enable ? 0x00 : 0x20); -} - -static void -kbc_ibf_process(atkbd_t *dev) -{ - /* IBF set, process both commands and data. */ - dev->status &= ~STAT_IFULL; - dev->kbc_state = KBC_STATE_MAIN_IBF; - if (dev->status & STAT_CD) - kbc_process_cmd(dev); - else { - set_enable_kbd(dev, 1); - dev->key_wantcmd = 1; - dev->key_dat = dev->ib; - dev->kbc_state = KBC_STATE_SEND_KBD; - } -} - -static void -kbc_scan_kbd_at(atkbd_t *dev) -{ - if (!(dev->mem[0x20] & 0x10)) { - /* Both OBF and IBF clear and keyboard is enabled. */ - /* XT mode. */ - if (dev->mem[0x20] & 0x20) { - if (dev->out_new != -1) { - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - dev->kbc_state = KBC_STATE_MAIN_IBF; - } else if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - /* AT mode. */ - } else { - // dev->t = dev->mem[0x28]; - if (dev->mem[0x2e] != 0x00) { - // if (!(dev->t & 0x02)) - // return; - dev->mem[0x2e] = 0x00; - } - dev->output_port &= 0xbf; - if (dev->out_new != -1) { - /* In our case, we never have noise on the line, so we can simplify this. */ - /* Read data from the keyboard. */ - if (dev->mem[0x20] & 0x40) { - if ((dev->mem[0x20] & 0x08) || (dev->input_port & 0x80)) - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->mem[0x2d] = (dev->out_new == 0xf0) ? 0x80 : 0x00; - } else - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - } - } -} - -static void write_output(atkbd_t *dev, uint8_t val); - -static void -kbc_poll_at(atkbd_t *dev) -{ - switch (dev->kbc_state) { - case KBC_STATE_RESET: - if (dev->status & STAT_IFULL) { - dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; - if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) - kbc_process_cmd(dev); - } - break; - case KBC_STATE_MAIN_IBF: - default: - if (dev->status & STAT_OFULL) { - /* OBF set, wait until it is cleared but still process commands. */ - if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) { - dev->status &= ~STAT_IFULL; - kbc_process_cmd(dev); - } - } else if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - else if (!(dev->mem[0x20] & 0x10)) - dev->kbc_state = KBC_STATE_MAIN_KBD; - break; - case KBC_STATE_MAIN_KBD: - case KBC_STATE_MAIN_BOTH: - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - else { - (void) kbc_scan_kbd_at(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - break; - case KBC_STATE_KBC_OUT: - /* Keyboard controller command want to output multiple bytes. */ - if (dev->status & STAT_IFULL) { - /* Data from host aborts dumping. */ - dev->kbc_state = KBC_STATE_MAIN_IBF; - kbc_ibf_process(dev); - } - /* Do not continue dumping until OBF is clear. */ - if (!(dev->status & STAT_OFULL)) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->key_ctrl_queue[dev->key_ctrl_queue_start]); - add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - break; - case KBC_STATE_KBC_PARAM: - /* Keyboard controller command wants data, wait for said data. */ - if (dev->status & STAT_IFULL) { - /* Command written, abort current command. */ - if (dev->status & STAT_CD) - dev->kbc_state = KBC_STATE_MAIN_IBF; - - dev->status &= ~STAT_IFULL; - kbc_process_cmd(dev); - } - break; - case KBC_STATE_SEND_KBD: - if (!dev->key_wantcmd) - dev->kbc_state = KBC_STATE_SCAN_KBD; - break; - case KBC_STATE_SCAN_KBD: - kbc_scan_kbd_at(dev); - break; - } -} - -/* - Correct Procedure: - 1. Controller asks the device (keyboard or mouse) for a byte. - 2. The device, unless it's in the reset or command states, sees if there's anything to give it, - and if yes, begins the transfer. - 3. The controller checks if there is a transfer, if yes, transfers the byte and sends it to the host, - otherwise, checks the next device, or if there is no device left to check, checks if IBF is full - and if yes, processes it. - */ -static int -kbc_scan_kbd_ps2(atkbd_t *dev) -{ - if (dev->out_new != -1) { - kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00); - dev->out_new = -1; - dev->kbc_state = KBC_STATE_MAIN_IBF; - return 1; - } - - return 0; -} - -static int -kbc_scan_aux_ps2(atkbd_t *dev) -{ - if (dev->out_new_mouse != -1) { - kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse & 0xff); - add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00); - dev->out_new_mouse = -1; - dev->kbc_state = KBC_STATE_MAIN_IBF; - return 1; - } - - return 0; -} - -static void -kbc_poll_ps2(atkbd_t *dev) -{ - switch (dev->kbc_state) { - case KBC_STATE_RESET: - if (dev->status & STAT_IFULL) { - dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL; - if ((dev->status & STAT_CD) && (dev->ib == 0xaa)) - kbc_process_cmd(dev); - } - break; - case KBC_STATE_MAIN_IBF: - default: - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - else if (!(dev->status & STAT_OFULL)) { - if (dev->mem[0x20] & 0x20) { - if (!(dev->mem[0x20] & 0x10)) { - dev->output_port &= 0xbf; - dev->kbc_state = KBC_STATE_MAIN_KBD; - } - } else { - dev->output_port &= 0xf7; - if (dev->mem[0x20] & 0x10) - dev->kbc_state = KBC_STATE_MAIN_MOUSE; - else { - dev->output_port &= 0xbf; - dev->kbc_state = KBC_STATE_MAIN_BOTH; - } - } - } - break; - case KBC_STATE_MAIN_KBD: - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - else { - (void) kbc_scan_kbd_ps2(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - break; - case KBC_STATE_MAIN_MOUSE: - if (dev->status & STAT_IFULL) - kbc_ibf_process(dev); - else { - (void) kbc_scan_aux_ps2(dev); - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - break; - case KBC_STATE_MAIN_BOTH: - if (kbc_scan_kbd_ps2(dev)) - dev->kbc_state = KBC_STATE_MAIN_IBF; - else - dev->kbc_state = KBC_STATE_MAIN_MOUSE; - break; - case KBC_STATE_KBC_OUT: - /* Keyboard controller command want to output multiple bytes. */ - if (dev->status & STAT_IFULL) { - /* Data from host aborts dumping. */ - dev->kbc_state = KBC_STATE_MAIN_IBF; - kbc_ibf_process(dev); - } - /* Do not continue dumping until OBF is clear. */ - if (!(dev->status & STAT_OFULL)) { - kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff); - add_to_kbc_queue_front(dev, dev->key_ctrl_queue[dev->key_ctrl_queue_start], 0, 0x00); - dev->key_ctrl_queue_start = (dev->key_ctrl_queue_start + 1) & 0x3f; - if (dev->key_ctrl_queue_start == dev->key_ctrl_queue_end) - dev->kbc_state = KBC_STATE_MAIN_IBF; - } - break; - case KBC_STATE_KBC_PARAM: - /* Keyboard controller command wants data, wait for said data. */ - if (dev->status & STAT_IFULL) { - /* Command written, abort current command. */ - if (dev->status & STAT_CD) - dev->kbc_state = KBC_STATE_MAIN_IBF; - - dev->status &= ~STAT_IFULL; - kbc_process_cmd(dev); - } - break; - case KBC_STATE_SEND_KBD: - if (!dev->key_wantcmd) - dev->kbc_state = KBC_STATE_SCAN_KBD; - break; - case KBC_STATE_SCAN_KBD: - (void) kbc_scan_kbd_ps2(dev); - break; - case KBC_STATE_SEND_MOUSE: - if (!dev->mouse_wantcmd) - dev->kbc_state = KBC_STATE_SCAN_MOUSE; - break; - case KBC_STATE_SCAN_MOUSE: - (void) kbc_scan_aux_ps2(dev); - break; - } -} - -static void -kbc_poll_kbd(atkbd_t *dev) -{ - switch (dev->kbd_state) { - case DEV_STATE_MAIN_1: - /* Process the command if needed and then return to main loop #2. */ - if (dev->key_wantcmd) { - kbd_log("ATkbc: Processing keyboard command %02X...\n", dev->key_dat); - kbc_queue_reset(dev, 4); - // dev->out_new = -1; - kbd_process_cmd(dev); - dev->key_wantcmd = 0; - } else - dev->kbd_state = DEV_STATE_MAIN_2; - break; - case DEV_STATE_MAIN_2: - /* Output from scan queue if needed and then return to main loop #1. */ - if (keyboard_scan && (dev->out_new == -1) && (dev->key_queue_start != dev->key_queue_end)) { - kbd_log("ATkbc: %02X (DATA) on channel 1\n", dev->key_queue[dev->key_queue_start]); - dev->out_new = dev->key_queue[dev->key_queue_start]; - dev->key_queue_start = (dev->key_queue_start + 1) & 0xf; - } - if (!keyboard_scan || dev->key_wantcmd) - dev->kbd_state = DEV_STATE_MAIN_1; - break; - case DEV_STATE_MAIN_OUT: - /* If host wants to send command while we're sending a byte to host, process the command. */ - if (dev->key_wantcmd) { - kbd_log("ATkbc: Processing keyboard command %02X...\n", dev->key_dat); - kbc_queue_reset(dev, 4); - kbd_process_cmd(dev); - dev->key_wantcmd = 0; - break; - } - /* FALLTHROUGH */ - case DEV_STATE_MAIN_WANT_IN: - /* Output command response and then wait for host data. */ - if ((dev->out_new == -1) && (dev->key_cmd_queue_start != dev->key_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 1\n", dev->key_cmd_queue[dev->key_cmd_queue_start]); - dev->out_new = dev->key_cmd_queue[dev->key_cmd_queue_start]; - dev->key_cmd_queue_start = (dev->key_cmd_queue_start + 1) & 0xf; - } - if (dev->key_cmd_queue_start == dev->key_cmd_queue_end) - dev->kbd_state = (dev->kbd_state == DEV_STATE_MAIN_OUT) ? DEV_STATE_MAIN_2 : DEV_STATE_MAIN_IN; - break; - case DEV_STATE_MAIN_IN: - /* Wait for host data. */ - if (dev->key_wantcmd) { - kbd_log("ATkbc: Processing keyboard command %02X parameter %02X...\n", dev->key_command, dev->key_dat); - kbc_queue_reset(dev, 4); - // dev->out_new = -1; - kbd_process_cmd(dev); - dev->key_wantcmd = 0; - } - break; - } -} - -static void -kbc_poll_aux(atkbd_t *dev) -{ - switch (dev->mouse_state) { - case DEV_STATE_MAIN_1: - /* Process the command if needed and then return to main loop #2. */ - if (dev->mouse_wantcmd) { - kbd_log("ATkbc: Processing mouse command %02X...\n", dev->mouse_dat); - kbc_queue_reset(dev, 3); - // dev->out_new_mouse = -1; - dev->mouse_state = DEV_STATE_MAIN_OUT; - mouse_write(dev->mouse_dat, mouse_p); - if ((dev->mouse_dat == 0xe8) || (dev->mouse_dat == 0xf3)) - dev->mouse_state = DEV_STATE_MAIN_WANT_IN; - dev->mouse_wantcmd = 0; - } else - dev->mouse_state = DEV_STATE_MAIN_2; - break; - case DEV_STATE_MAIN_2: - /* Output from scan queue if needed and then return to main loop #1. */ - if (mouse_scan && (dev->out_new_mouse == -1) && (dev->mouse_queue_start != dev->mouse_queue_end)) { - kbd_log("ATkbc: %02X (DATA) on channel 2\n", dev->mouse_queue[dev->mouse_queue_start]); - dev->out_new_mouse = dev->mouse_queue[dev->mouse_queue_start]; - dev->mouse_queue_start = (dev->mouse_queue_start + 1) & 0xf; - } - if (!mouse_scan || dev->mouse_wantcmd) - dev->mouse_state = DEV_STATE_MAIN_1; - break; - case DEV_STATE_MAIN_OUT: - /* If host wants to send command while we're sending a byte to host, process the command. */ - if (dev->mouse_wantcmd) { - kbd_log("ATkbc: Processing mouse command %02X...\n", dev->mouse_dat); - kbc_queue_reset(dev, 3); - dev->mouse_state = DEV_STATE_MAIN_OUT; - mouse_write(dev->mouse_dat, mouse_p); - if ((dev->mouse_dat == 0xe8) || (dev->mouse_dat == 0xf3)) - dev->mouse_state = DEV_STATE_MAIN_WANT_IN; - dev->mouse_wantcmd = 0; - break; - } - /* FALLTHROUGH */ - case DEV_STATE_MAIN_WANT_IN: - /* Output command response and then wait for host data. */ - if ((dev->out_new_mouse == -1) && (dev->mouse_cmd_queue_start != dev->mouse_cmd_queue_end)) { - kbd_log("ATkbc: %02X (CMD ) on channel 2\n", dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]); - dev->out_new_mouse = dev->mouse_cmd_queue[dev->mouse_cmd_queue_start]; - dev->mouse_cmd_queue_start = (dev->mouse_cmd_queue_start + 1) & 0xf; - } - if (dev->mouse_cmd_queue_start == dev->mouse_cmd_queue_end) - dev->mouse_state = (dev->mouse_state == DEV_STATE_MAIN_OUT) ? DEV_STATE_MAIN_2 : DEV_STATE_MAIN_IN; - break; - case DEV_STATE_MAIN_IN: - /* Wait for host data. */ - if (dev->mouse_wantcmd) { - kbd_log("ATkbc: Processing mouse command parameter %02X...\n", dev->mouse_dat); - kbc_queue_reset(dev, 3); - // dev->out_new_mouse = -1; - dev->mouse_state = DEV_STATE_MAIN_OUT; - mouse_write(dev->mouse_dat, mouse_p); - dev->mouse_wantcmd = 0; - } - break; - } -} - -/* TODO: State machines for controller, keyboard, and mouse. */ -static void -kbd_poll(void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - - timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); - - /* TODO: Use a fuction pointer for this (also needed to the AMI KBC mode switching) - and implement the password security state. */ - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) - kbc_poll_ps2(dev); - else - kbc_poll_at(dev); - - kbc_poll_kbd(dev); - - if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && mouse_write) - kbc_poll_aux(dev); - - // if (kbc_ports[0] && kbc_ports[0]>-priv) - // kbc_ports[0]>poll(kbc_ports[0]>-priv); - - // if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && kbc_ports[1] && kbc_ports[1]>-priv) - // kbc_ports[1]>poll(kbc_ports[1]>-priv); -} - -static void -add_data_vals(atkbd_t *dev, uint8_t *val, uint8_t len) -{ - int i; - - for (i = 0; i < len; i++) - add_data_kbd_queue(dev, val[i]); -} - -static void -add_data_kbd(uint16_t val) -{ - atkbd_t *dev = SavedKbd; - uint8_t fake_shift[4]; - uint8_t num_lock = 0, shift_states = 0; - - keyboard_get_states(NULL, &num_lock, NULL); - shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; - - 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: - add_data_kbd_queue(dev, val); - break; - } -} - -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 0 - /* PS/2: Handle IRQ's. */ - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - /* IRQ 12 */ - picint_common(1 << 12, 0, val & 0x20); - - /* IRQ 1 */ - picint_common(1 << 1, 0, val & 0x10); - } -#endif - - /* AT, PS/2: Handle A20. */ - if ((old ^ val) & 0x02) { /* A20 enable change */ - mem_a20_key = val & 0x02; - mem_a20_recalc(); - flushmmucache(); - } - - /* AT, PS/2: Handle reset. */ - /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, - we just do everything on release. */ - if ((old ^ val) & 0x01) { /*Reset*/ - if (!(val & 0x01)) { /* Pin 0 selected. */ - /* Pin 0 selected. */ - kbd_log("write_output(): Pulse reset!\n"); - if (machines[machine].flags & MACHINE_COREBOOT) { - /* The SeaBIOS hard reset code attempts a KBC reset if ACPI RESET_REG - is not available. However, the KBC reset is normally a soft reset, so - SeaBIOS gets caught in a soft reset loop as it tries to hard reset the - machine. Hack around this by making the KBC reset a hard reset only on - coreboot machines. */ - pc_reset_hard(); - } else { - softresetx86(); /*Pulse reset!*/ - cpu_set_edx(); - flushmmucache(); - if (kbc_ven == KBC_VEN_ALI) - smbase = 0x00030000; - } - } - } - - /* Do this here to avoid an infinite reset loop. */ - dev->output_port = val; -} - -static void -write_output_fast_a20(atkbd_t *dev, uint8_t val) -{ - uint8_t old = dev->output_port; - kbd_log("ATkbc: write output port in fast A20 mode: %02X (old: %02X)\n", val, dev->output_port); - - /* AT, PS/2: Handle A20. */ - if ((old ^ val) & 0x02) { /* A20 enable change */ - mem_a20_key = val & 0x02; - mem_a20_recalc(); - flushmmucache(); - } - - /* Do this here to avoid an infinite reset loop. */ - dev->output_port = val; -} - -static void -write_cmd(atkbd_t *dev, uint8_t val) -{ - kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0x20]); - - /* 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[0x20] &= ~CCB_TRANSLATE; - } else if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { - if (val & 0x10) - dev->mem[0x2e] = 0x01; - } - - kbd_log("ATkbc: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); - - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { - /* Update the output port to mirror the IBF and OBF bits, if active. */ - write_output(dev, (dev->output_port & 0x0f) | ((val & 0x03) << 4) | ((val & 0x20) ? 0xc0 : 0x00)); - } - - kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0x20], 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 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_to_kbc_queue_front(dev, 0xf1, 0, 0x00); - 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_to_kbc_queue_front(dev, 0x00, 0, 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_to_kbc_queue_front(dev, 0x42, 0, 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 ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) { - /* Bit 3, 2: - 1, 1: TriGem logo; - 1, 0: Garbled logo; - 0, 1: Epson logo; - 0, 0: Generic AMI logo. */ - if (dev->pci) - fixed_bits |= 8; - add_to_kbc_queue_front(dev, dev->input_port | fixed_bits, 0, 0x00); - } 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; - dev->kbc_state = KBC_STATE_KBC_PARAM; - return 0; - } - break; - - case 0xd4: /* write to mouse */ - kbd_log("ATkbc: write to mouse\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - return 0; - - case 0xf0 ... 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 ... 0x5f: - kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); - dev->mem[(dev->command & 0x1f) + 0x20] = val; - if (dev->command == 0x60) - write_cmd(dev, val); - return 0; - - case 0xa5: /* get extended controller RAM */ - kbd_log("ATkbc: AMI - get extended controller RAM\n"); - add_to_kbc_queue_front(dev, dev->mem[val], 0, 0x00); - 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->kbc_state = KBC_STATE_KBC_PARAM; - 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; - uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; - - switch (val) { - case 0x00 ... 0x1f: - kbd_log("ATkbc: AMI - alias read from %08X\n", val); - add_to_kbc_queue_front(dev, dev->mem[val + 0x20], 0, 0x00); - return 0; - - case 0x40 ... 0x5f: - kbd_log("ATkbc: AMI - alias write to %08X\n", dev->command); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - return 0; - - case 0xa0: /* copyright message */ - kbc_queue_add(dev, 0x28, 0); - kbc_queue_add(dev, 0x00, 0); - dev->kbc_state = KBC_STATE_KBC_OUT; - break; - - case 0xa1: /* get controller version */ - kbd_log("ATkbc: AMI - get controller version\n"); - if ((kbc_ven == KBC_VEN_TG) || (kbc_ven == KBC_VEN_TG_GREEN)) - add_to_kbc_queue_front(dev, 'Z', 0, 0x00); - else if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - if (kbc_ven == KBC_VEN_ALI) - add_to_kbc_queue_front(dev, 'F', 0, 0x00); - else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI) - add_to_kbc_queue_front(dev, '5', 0, 0x00); - else if (cpu_64bitbus) - add_to_kbc_queue_front(dev, 'R', 0, 0x00); - else if (is486) - add_to_kbc_queue_front(dev, 'P', 0, 0x00); - else - add_to_kbc_queue_front(dev, 'H', 0, 0x00); - } else if (is386 && !is486) { - if (cpu_16bitbus) - add_to_kbc_queue_front(dev, 'D', 0, 0x00); - else - add_to_kbc_queue_front(dev, 'B', 0, 0x00); - } else if (!is386) - add_to_kbc_queue_front(dev, '8', 0, 0x00); - else - add_to_kbc_queue_front(dev, 'F', 0, 0x00); - 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_to_kbc_queue_front(dev, 0x00, 0, 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_to_kbc_queue_front(dev, 0x00, 0, 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; - } else { - kbd_log("ATkbc: get extended controller RAM\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - } - return 0; - - case 0xa6: /* read clock */ - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) { - kbd_log("ATkbc: AMI - read clock\n"); - add_to_kbc_queue_front(dev, (dev->ami_stat & 1) ? 0xff : 0x00, 0, 0x00); - 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_to_kbc_queue_front(dev, (dev->ami_stat & 2) ? 0xff : 0x00, 0, 0x00); - return 0; - } - break; - - case 0xaf: /* set extended controller RAM */ - if (kbc_ven == KBC_VEN_ALI) { - kbd_log("ATkbc: Award/ALi/VIA keyboard controller revision\n"); - add_to_kbc_queue_front(dev, 0x43, 0, 0x00); - } else { - kbd_log("ATkbc: set extended controller RAM\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - dev->secr_phase = 1; - } - return 0; - - case 0xb0 ... 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 (!(dev->flags & DEVICE_PCI) || (val > 0xb1)) - dev->input_port &= ~(1 << (val & 0x03)); - add_to_kbc_queue_front(dev, 0x00, 0, 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 (!(dev->flags & DEVICE_PCI)) - write_output(dev, dev->output_port & ~(4 << (val & 0x01))); - add_to_kbc_queue_front(dev, 0x00, 0, 0x00); - return 0; - - case 0xb8 ... 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 (!(dev->flags & DEVICE_PCI) || (val > 0xb9)) { - dev->input_port |= (1 << (val & 0x03)); - add_to_kbc_queue_front(dev, 0x00, 0, 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 (!(dev->flags & DEVICE_PCI)) - write_output(dev, dev->output_port | (4 << (val & 0x01))); - add_to_kbc_queue_front(dev, 0x00, 0, 0x00); - return 0; - - case 0xc1: /* write input port */ - kbd_log("ATkbc: AMI MegaKey - write input port\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - 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_to_kbc_queue_front(dev, 0x00, 0, 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_to_kbc_queue_front(dev, 0x00, 0, 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->ami_flags &= 0xfb; - 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->ami_flags |= 0x04; - 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_to_kbc_queue_front(dev, 0x00, 0, 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_to_kbc_queue_front(dev, 0x00, 0, 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 ... 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; - dev->kbc_state = KBC_STATE_KBC_PARAM; - 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_to_kbc_queue_front(dev, t3100e_config_get(), 0, 0x00); - return 0; - - case 0xb5: /* T3100e: Get colour / mono byte */ - kbd_log("ATkbc: T3100e: Get colour / mono byte\n"); - add_to_kbc_queue_front(dev, t3100e_mono_get(), 0, 0x00); - return 0; - - case 0xb6: /* T3100e: Set colour / mono byte */ - kbd_log("ATkbc: T3100e: Set colour / mono byte\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - 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_to_kbc_queue_front(dev, 0x04, 0, 0x00); - else - add_to_kbc_queue_front(dev, 0x00, 0, 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_to_kbc_queue_front(dev, dev->input_port, 0, 0x00); - return 0; - } - - return write64_generic(dev, val); -} - -static void -kbd_key_reset(atkbd_t *dev, int do_fa) -{ - dev->out_new = -1; - kbc_queue_reset(dev, 1); - - dev->kbd_last_scan_code = 0x00; - - /* Set scan code set to 2. */ - keyboard_mode = 0x02; - set_scancode_map(dev); - - /* The BAT enables scanning. */ - keyboard_scan = 1; - - dev->sc_or = 0; - - if (do_fa) - add_data_kbd_front(dev, 0xfa); - add_data_kbd_front(dev, 0xaa); - - if (!do_fa) - dev->kbd_state = DEV_STATE_MAIN_OUT; -} - -static void -kbd_aux_reset(atkbd_t *dev, int do_fa) -{ - dev->out_new_mouse = -1; - kbc_queue_reset(dev, 2); - - /* The BAT enables scanning. */ - mouse_scan = 1; - - if (!do_fa) { - add_data_kbd_front(dev, 0xaa); - add_data_kbd_front(dev, 0x00); - - dev->mouse_state = DEV_STATE_MAIN_OUT; - } -} - -void -keyboard_at_mouse_reset(void) -{ - atkbd_t *dev = SavedKbd; - - kbd_aux_reset(dev, 1); -} - -static void -kbd_process_cmd(void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - - dev->kbd_state = DEV_STATE_MAIN_OUT; - - 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 (dev->key_dat == dev->key_command) { - /* Respond NAK and ignore it. */ - add_data_kbd_front(dev, 0xfe); - dev->key_command = 0x00; - return; - } - - switch (dev->key_command) { - case 0xed: /* set/reset LEDs */ - add_data_kbd_front(dev, 0xfa); - kbd_log("ATkbd: set LEDs [%02x]\n", dev->key_dat); - break; - - case 0xf0: /* get/set scancode set */ - add_data_kbd_front(dev, 0xfa); - if (dev->key_dat == 0) { - kbd_log("Get scan code set: %02X\n", keyboard_mode); - add_data_kbd_front(dev, keyboard_mode); - } else { - if (dev->key_dat <= 3) { - keyboard_mode = dev->key_dat; - kbd_log("Scan code set now: %02X\n", keyboard_mode); - } - set_scancode_map(dev); - } - break; - - case 0xf3: /* set typematic rate/delay */ - add_data_kbd_front(dev, 0xfa); - break; - - default: - kbd_log("ATkbd: bad keyboard 0060 write %02X command %02X\n", dev->key_dat, dev->key_command); - add_data_kbd_front(dev, 0xfe); - break; - } - - /* Keyboard command is now done. */ - dev->key_command = 0x00; - } else { - /* No keyboard command in progress. */ - dev->key_command = 0x00; - - switch (dev->key_dat) { - case 0x00 ... 0x7f: - kbd_log("ATkbd: invalid command %02X\n", dev->key_dat); - add_data_kbd_front(dev, 0xfe); - break; - - case 0xed: /* set/reset LEDs */ - kbd_log("ATkbd: set/reset leds\n"); - add_data_kbd_front(dev, 0xfa); - - dev->key_wantdata = 1; - dev->kbd_state = DEV_STATE_MAIN_WANT_IN; - break; - - case 0xee: /* diagnostic echo */ - kbd_log("ATkbd: ECHO\n"); - add_data_kbd_front(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_front(dev, 0xfa); - dev->key_wantdata = 1; - dev->kbd_state = DEV_STATE_MAIN_WANT_IN; - break; - - case 0xf2: /* read ID */ - 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_front(dev, 0xfa); - add_data_kbd_front(dev, 0xab); - add_data_kbd_front(dev, 0x83); - break; - - case 0xf3: /* set typematic rate/delay */ - kbd_log("ATkbd: set typematic rate/delay\n"); - add_data_kbd_front(dev, 0xfa); - dev->key_wantdata = 1; - dev->kbd_state = DEV_STATE_MAIN_WANT_IN; - break; - - case 0xf4: /* enable keyboard */ - kbd_log("ATkbd: enable keyboard\n"); - add_data_kbd_front(dev, 0xfa); - keyboard_scan = 1; - break; - - case 0xf5: /* set defaults and disable keyboard */ - case 0xf6: /* set defaults */ - kbd_log("ATkbd: set defaults%s\n", (dev->key_dat == 0xf6) ? "" : " and disable keyboard"); - keyboard_scan = (dev->key_dat == 0xf6); - kbd_log("dev->key_dat = %02X, keyboard_scan = %i, dev->mem[0x20] = %02X\n", - dev->key_dat, keyboard_scan, dev->mem[0]); - add_data_kbd_front(dev, 0xfa); - - keyboard_set3_all_break = 0; - keyboard_set3_all_repeat = 0; - memset(keyboard_set3_flags, 0, 512); - keyboard_mode = 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_front(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_front(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_front(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_front(dev, 0xfa); - keyboard_set3_all_repeat = 1; - keyboard_set3_all_break = 1; - break; - - case 0xfe: /* resend last scan code */ - kbd_log("ATkbd: resend last scan code\n"); - add_data_kbd_front(dev, dev->kbd_last_scan_code); - break; - - case 0xff: /* reset */ - kbd_log("ATkbd: kbd reset\n"); - kbd_key_reset(dev, 1); - break; - - default: - kbd_log("ATkbd: bad keyboard command %02X\n", dev->key_dat); - add_data_kbd_front(dev, 0xfe); - } - - /* If command needs data, remember command. */ - if (dev->key_wantdata == 1) - dev->key_command = dev->key_dat; - } -} - -static void -kbc_process_cmd(void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - int i = 0, bad = 1; - uint8_t mask, kbc_ven = dev->flags & KBC_VEN_MASK; - uint8_t cmd_ac_conv[16] = { 0x0b, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21 }; - - if (dev->status & STAT_CD) { - /* Controller command. */ - dev->want60 = 0; - dev->kbc_state = KBC_STATE_MAIN_IBF; - - /* Clear the keyboard controller queue. */ - kbc_queue_reset(dev, 0); - - switch (dev->ib) { - /* Read data from KBC memory. */ - case 0x20 ... 0x3f: - add_to_kbc_queue_front(dev, dev->mem[dev->ib], 0, 0x00); - break; - - /* Write data to KBC memory. */ - case 0x60 ... 0x7f: - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - break; - - case 0xaa: /* self-test */ - kbd_log("ATkbc: self-test\n"); - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - if (dev->kbc_state != KBC_STATE_RESET) { - kbd_log("ATkbc: self-test reinitialization\n"); - /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ - /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ - dev->input_port = dev->input_port & 0xff; - write_output(dev, 0x4b); - } - - dev->status = (dev->status & 0x0f) | 0x60; - - dev->mem[0x20] = 0x30; - dev->mem[0x21] = 0x01; - dev->mem[0x22] = 0x0b; - dev->mem[0x25] = 0x02; - dev->mem[0x27] = 0xf8; - dev->mem[0x28] = 0xce; - dev->mem[0x29] = 0x0b; - dev->mem[0x2a] = 0x10; - dev->mem[0x2b] = 0x20; - dev->mem[0x2c] = 0x15; - dev->mem[0x30] = 0x0b; - } else { - if (dev->kbc_state != KBC_STATE_RESET) { - kbd_log("ATkbc: self-test reinitialization\n"); - /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ - /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ - dev->input_port = dev->input_port & 0xff; - write_output(dev, 0xcf); - } - - dev->status = (dev->status & 0x0f) | 0x60; - - dev->mem[0x20] = 0x10; - dev->mem[0x21] = 0x01; - dev->mem[0x22] = 0x06; - dev->mem[0x25] = 0x01; - dev->mem[0x27] = 0xfb; - dev->mem[0x28] = 0xe0; - dev->mem[0x29] = 0x06; - dev->mem[0x2a] = 0x10; - dev->mem[0x2b] = 0x20; - dev->mem[0x2c] = 0x15; - } - - dev->out_new = dev->out_new_mouse = -1; - kbc_queue_reset(dev, 0); - - // dev->kbc_state = KBC_STATE_MAIN_IBF; - dev->kbc_state = KBC_STATE_KBC_OUT; - - // add_to_kbc_queue_front(dev, 0x55, 0, 0x00); - kbc_queue_add(dev, 0x55, 0); - break; - - case 0xab: /* interface test */ - kbd_log("ATkbc: interface test\n"); - add_to_kbc_queue_front(dev, 0x00, 0, 0x00); /*no error*/ - break; - - case 0xac: /* diagnostic dump */ - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - kbd_log("ATkbc: diagnostic dump\n"); - dev->mem[0x30] = (dev->input_port & 0xf0) | 0x80; - dev->mem[0x31] = dev->output_port; - dev->mem[0x32] = 0x00; /* T0 and T1. */ - dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ - /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ - for (i = 0; i < 20; i++) { - kbc_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4], 0); - kbc_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] & 0x0f], 0); - kbc_queue_add(dev, 0x39, 0); - } - dev->kbc_state = KBC_STATE_KBC_OUT; - } - 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 0xc7: /* set port1 bits */ - kbd_log("ATkbc: Phoenix - set port1 bits\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - break; - - case 0xca: /* read keyboard mode */ - kbd_log("ATkbc: AMI - read keyboard mode\n"); - add_to_kbc_queue_front(dev, dev->ami_flags, 0, 0x00); - break; - - case 0xcb: /* set keyboard mode */ - kbd_log("ATkbc: AMI - set keyboard mode\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - 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[0x20] & 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; - dev->kbc_state = KBC_STATE_KBC_PARAM; - break; - - case 0xd2: /* write keyboard output buffer */ - kbd_log("ATkbc: write keyboard output buffer\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - break; - - case 0xdd: /* disable A20 address line */ - case 0xdf: /* enable A20 address line */ - kbd_log("ATkbc: %sable A20\n", (dev->ib == 0xdd) ? "dis" : "en"); - write_output_fast_a20(dev, (dev->output_port & 0xfd) | (dev->ib & 0x02)); - break; - - case 0xe0: /* read test inputs */ - kbd_log("ATkbc: read test inputs\n"); - add_to_kbc_queue_front(dev, 0x00, 0, 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, dev->ib); - - kbd_log(bad ? "ATkbc: bad controller command %02X\n" : "", dev->ib); - } - - /* If the command needs data, remember the command. */ - if (dev->want60) - dev->command = dev->ib; - } else if (dev->want60) { - /* Write data to controller. */ - dev->want60 = 0; - dev->kbc_state = KBC_STATE_MAIN_IBF; - - switch (dev->command) { - case 0x60 ... 0x7f: - dev->mem[(dev->command & 0x1f) + 0x20] = dev->ib; - if (dev->command == 0x60) - write_cmd(dev, dev->ib); - break; - - case 0xc7: /* set port1 bits */ - kbd_log("ATkbc: Phoenix - set port1 bits\n"); - dev->input_port |= dev->ib; - break; - - case 0xd1: /* write output port */ - kbd_log("ATkbc: write output port\n"); - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpen Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - dev->ib &= ~0x0c; - dev->ib |= (dev->output_port & 0x0c); - } - write_output(dev, dev->ib | 0x01); - break; - - case 0xd2: /* write to keyboard output buffer */ - kbd_log("ATkbc: write to keyboard output buffer\n"); - add_to_kbc_queue_front(dev, dev->ib, 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(dev->ib); - break; - - case 0xd4: /* write to mouse */ - kbd_log("ATkbc: write to mouse (%02X)\n", dev->ib); - - if (dev->ib == 0xbb) - break; - - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - set_enable_mouse(dev, 1); - if (mouse_write) { - dev->mouse_wantcmd = 1; - dev->mouse_dat = dev->ib; - dev->kbc_state = KBC_STATE_SEND_MOUSE; - } 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, dev->ib); - - if (bad) { - kbd_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); - } - } - } -} - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - - kbd_log((port == 0x61) ? "" : "[%04X:%08X] ATkbc: write(%04X) = %02X\n", CS, cpu_state.pc, port, val); - - switch (port) { - case 0x60: - dev->status &= ~STAT_CD; - if (dev->want60 && (dev->command == 0xd1)) { - kbd_log("ATkbc: write output port\n"); - - /* Fast A20 - ignore all other bits. */ - val = (val & 0x02) | (dev->output_port & 0xfd); - - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - val &= ~0x0c; - val |= (dev->output_port & 0x0c); - } - - write_output_fast_a20(dev, val | 0x01); - - dev->want60 = 0; - dev->kbc_state = KBC_STATE_MAIN_IBF; - return; - } - break; - - case 0x64: - dev->status |= STAT_CD; - if (val == 0xd1) { - kbd_log("ATkbc: write output port\n"); - dev->want60 = 1; - dev->kbc_state = KBC_STATE_KBC_PARAM; - dev->command = 0xd1; - return; - } - break; - } - - dev->ib = val; - dev->status |= STAT_IFULL; -} - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - uint8_t ret = 0xff; - - 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; - /* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a bit the - output port (P2). - This also means that in AT mode, the IRQ is level-triggered. */ - if ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) - picintc(1 << 1); - break; - - case 0x64: - ret = dev->status; - break; - - default: - kbd_log("ATkbc: read(%04x) invalid!\n",port); - break; - } - - kbd_log((port == 0x61) ? "" : "[%04X:%08X] ATkbc: read (%04X) = %02X\n", CS, cpu_state.pc, 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->status = STAT_UNLOCKED; - dev->mem[0x20] = 0x01; - dev->mem[0x20] |= CCB_TRANSLATE; - dev->secr_phase = 0; - dev->key_wantdata = 0; - - /* Set up the correct Video Type bits. */ - if (!is286 || (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); - - /* Enable keyboard, disable mouse. */ - set_enable_kbd(dev, 0); - keyboard_scan = 0; - set_enable_mouse(dev, 0); - mouse_scan = 0; - - dev->out_new = dev->out_new_mouse = -1; - for (i = 0; i < 3; i++) - kbc_queue_reset(dev, i); - dev->kbd_last_scan_code = 0; - - dev->sc_or = 0; - - keyboard_mode = 0x02; - - memset(keyboard_set3_flags, 0, 512); - - set_scancode_map(dev); - - dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00; - dev->ami_stat |= 0x02; - - dev->output_port = 0xcd; - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - write_output(dev, 0x4b); - } else { - /* The real thing writes CF and then AND's it with BF. */ - write_output(dev, 0x8f); - } - - /* Stage 1. */ - dev->status = (dev->status & 0x0f) | (dev->input_port & 0xf0); - - /* Reset the keyboard. */ - kbd_key_reset(dev, 0); - - /* Reset the mouse. */ - kbd_aux_reset(dev, 0); -} - -/* 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); -} - -void -kbc_at_a20_reset(void) -{ - if (SavedKbd) { - SavedKbd->output_port = 0xcd; - if ((SavedKbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { - write_output(SavedKbd, 0x4b); - } else { - /* The real thing writes CF and then AND's it with BF. */ - write_output(SavedKbd, 0x8f); - } - } -} - -static void -kbd_close(void *priv) -{ - atkbd_t *dev = (atkbd_t *) priv; - int i, max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; - - 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; - - for (i = 0; i < max_ports; i++) { - if (kbc_ports[i] != NULL) { - free(kbc_ports[i]); - kbc_ports[i] = NULL; - } - } - - free(dev); -} - -static void * -kbd_init(const device_t *info) -{ - atkbd_t *dev; - int i, max_ports; - - dev = (atkbd_t *) malloc(sizeof(atkbd_t)); - memset(dev, 0x00, sizeof(atkbd_t)); - - dev->flags = info->local; - dev->pci = !!(info->flags & DEVICE_PCI); - - /* We need this, sadly. */ - SavedKbd = dev; - - video_reset(gfxcard[0]); - 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: - 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_ALI: - case KBC_VEN_TG: - case KBC_VEN_TG_GREEN: - 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; - } - - max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 2 : 1; - - for (i = 0; i < max_ports; i++) { - kbc_ports[i] = (kbc_port_t *) malloc(sizeof(kbc_port_t)); - memset(kbc_ports[i], 0x00, sizeof(kbc_port_t)); - } - - return (dev); -} - -const device_t keyboard_at_device = { - .name = "PC/AT Keyboard", - .internal_name = "keyboard_at", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_GENERIC, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_at_ami_device = { - .name = "PC/AT Keyboard (AMI)", - .internal_name = "keyboard_at_ami", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_AMI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_at_tg_ami_device = { - .name = "PC/AT Keyboard (TriGem AMI)", - .internal_name = "keyboard_at_tg_ami", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_TG, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_at_toshiba_device = { - .name = "PC/AT Keyboard (Toshiba)", - .internal_name = "keyboard_at_toshiba", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_TOSHIBA, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_at_olivetti_device = { - .name = "PC/AT Keyboard (Olivetti)", - .internal_name = "keyboard_at_olivetti", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_OLIVETTI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_at_ncr_device = { - .name = "PC/AT Keyboard (NCR)", - .internal_name = "keyboard_at_ncr", - .flags = 0, - .local = KBC_TYPE_ISA | KBC_VEN_NCR, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_ps1_device = { - .name = "PS/2 Keyboard (IBM PS/1)", - .internal_name = "keyboard_ps2_ps1", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_ps1_pci_device = { - .name = "PS/2 Keyboard (IBM PS/1)", - .internal_name = "keyboard_ps2_ps1_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_IBM_PS1, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_xi8088_device = { - .name = "PS/2 Keyboard (Xi8088)", - .internal_name = "keyboard_ps2_xi8088", - .flags = 0, - .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_ami_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_ami", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_AMI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_tg_ami_device = { - .name = "PS/2 Keyboard (TriGem AMI)", - .internal_name = "keyboard_ps2_tg_ami", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_mca_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_mca", - .flags = 0, - .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_mca_2_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_mca_2", - .flags = 0, - .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_quadtel_device = { - .name = "PS/2 Keyboard (Quadtel/MegaPC)", - .internal_name = "keyboard_ps2_quadtel", - .flags = 0, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_QUADTEL, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_pci_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_ami_pci_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_ami_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_AMI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_ali_pci_device = { - .name = "PS/2 Keyboard (ALi M5123/M1543C)", - .internal_name = "keyboard_ps2_ali_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_ALI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_intel_ami_pci_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_intel_ami_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_INTEL_AMI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_tg_ami_pci_device = { - .name = "PS/2 Keyboard (TriGem AMI)", - .internal_name = "keyboard_ps2_tg_ami_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_TG, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_ps2_acer_pci_device = { - .name = "PS/2 Keyboard (Acer 90M002A)", - .internal_name = "keyboard_ps2_acer_pci", - .flags = DEVICE_PCI, - .local = KBC_TYPE_PS2_NOREF | KBC_VEN_ACER, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = 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_mouse(uint8_t val) -{ - atkbd_t *dev = SavedKbd; - - if (!mouse_scan || (dev->mouse_queue_end >= 16)) { - kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i\n", !mouse_scan, (dev->mouse_queue_end >= 16)); - return; - } - kbc_queue_add(dev, val, 2); -} - -void -keyboard_at_adddata_mouse_cmd(uint8_t val) -{ - atkbd_t *dev = SavedKbd; - - if (dev->mouse_cmd_queue_end >= 16) { - kbd_log("ATkbc: Unable to add to queue, dev->mouse_cmd_queue_end >= 16\n"); - return; - } - kbc_queue_add(dev, val, 3); -} - -uint8_t -keyboard_at_mouse_pos(void) -{ - atkbd_t *dev = SavedKbd; - - return ((dev->mouse_queue_end - dev->mouse_queue_start) & 0xf); -} - -void -keyboard_at_set_a20_key(int state) -{ - atkbd_t *dev = SavedKbd; - - write_output(dev, (dev->output_port & 0xfd) | ((!!state) << 1)); -} diff --git a/src/device/mouse_ps2 - Cópia.c b/src/device/mouse_ps2 - Cópia.c deleted file mode 100644 index 1c8e0334d..000000000 --- a/src/device/mouse_ps2 - Cópia.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * 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. - * - * Implementation of PS/2 series Mouse devices. - * - * - * - * Authors: Fred N. van Kempen, - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mouse.h> - -enum { - MODE_STREAM, - MODE_REMOTE, - MODE_ECHO -}; - -typedef struct { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - - int mode; - - uint16_t flags; - uint8_t resolution; - uint8_t sample_rate; - - uint8_t command; - - int x, y, z, b; - - uint8_t last_data[6]; -} mouse_t; -#define FLAG_5BTN 0x100 /* using Intellimouse Optical mode */ -#define FLAG_INTELLI 0x80 /* device is IntelliMouse */ -#define FLAG_INTMODE 0x40 /* using Intellimouse mode */ -#define FLAG_SCALED 0x20 /* enable delta scaling */ -#define FLAG_ENABLED 0x10 /* dev is enabled for use */ -#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ - -int mouse_scan = 0; - -#ifdef ENABLE_MOUSE_PS2_LOG -int mouse_ps2_do_log = ENABLE_MOUSE_PS2_LOG; - -static void -mouse_ps2_log(const char *fmt, ...) -{ - va_list ap; - - if (mouse_ps2_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define mouse_ps2_log(fmt, ...) -#endif - -void -mouse_clear_data(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - dev->flags &= ~FLAG_CTRLDAT; -} - -static void -ps2_report_coordinates(mouse_t *dev, int cmd) -{ - uint8_t buff[3] = { 0x08, 0x00, 0x00 }; - int temp_z; - - if (dev->x > 255) { - dev->x = 255; - buff[0] |= 0x40; - } - if (dev->x < -256) { - dev->x = -256; - buff[0] |= 0x40; - } - if (dev->y > 255) { - dev->y = 255; - buff[0] |= 0x80; - } - if (dev->y < -256) { - dev->y = -256; - buff[0] |= 0x80; - } - if (dev->z < -8) - dev->z = -8; - if (dev->z > 7) - dev->z = 7; - - if (dev->x < 0) - buff[0] |= 0x10; - if (dev->y < 0) - buff[0] |= 0x20; - if (mouse_buttons & 0x01) - buff[0] |= 0x01; - if (mouse_buttons & 0x02) - buff[0] |= 0x02; - if (dev->flags & FLAG_INTELLI) { - if (mouse_buttons & 0x04) - buff[0] |= 0x04; - } - buff[1] = (dev->x & 0xff); - buff[2] = (dev->y & 0xff); - - if (cmd) { - keyboard_at_adddata_mouse_cmd(buff[0]); - keyboard_at_adddata_mouse_cmd(buff[1]); - keyboard_at_adddata_mouse_cmd(buff[2]); - } else { - keyboard_at_adddata_mouse(buff[0]); - keyboard_at_adddata_mouse(buff[1]); - keyboard_at_adddata_mouse(buff[2]); - } - if (dev->flags & FLAG_INTMODE) { - temp_z = dev->z & 0x0f; - if ((dev->flags & FLAG_5BTN)) { - if (mouse_buttons & 8) - temp_z |= 0x10; - if (mouse_buttons & 16) - temp_z |= 0x20; - } else { - /* The wheel coordinate is sign-extended. */ - if (temp_z & 0x08) - temp_z |= 0xf0; - } - if (cmd) - keyboard_at_adddata_mouse_cmd(temp_z); - else - keyboard_at_adddata_mouse(temp_z); - } - - dev->x = dev->y = dev->z = 0; -} - -static void -ps2_write(uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - uint8_t temp; - - if (dev->flags & FLAG_CTRLDAT) { - dev->flags &= ~FLAG_CTRLDAT; - - if (val == 0xff) - goto mouse_reset; - - switch (dev->command) { - case 0xe8: /* set mouse resolution */ - dev->resolution = val; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xf3: /* set sample rate */ - dev->sample_rate = val; - keyboard_at_adddata_mouse_cmd(0xfa); /* Command response */ - break; - - default: - keyboard_at_adddata_mouse_cmd(0xfc); - } - } else { - dev->command = val; - - switch (dev->command) { - case 0xe6: /* set scaling to 1:1 */ - dev->flags &= ~FLAG_SCALED; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xe7: /* set scaling to 2:1 */ - dev->flags |= FLAG_SCALED; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xe8: /* set mouse resolution */ - dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xe9: /* status request */ - keyboard_at_adddata_mouse_cmd(0xfa); - temp = (dev->flags & 0x30); - if (mouse_buttons & 1) - temp |= 4; - if (mouse_buttons & 2) - temp |= 1; - if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) - temp |= 2; - keyboard_at_adddata_mouse_cmd(temp); - keyboard_at_adddata_mouse_cmd(dev->resolution); - keyboard_at_adddata_mouse_cmd(dev->sample_rate); - break; - - case 0xea: /* set stream */ - dev->flags &= ~FLAG_CTRLDAT; - mouse_scan = 1; - keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */ - break; - - case 0xeb: /* Get mouse data */ - keyboard_at_adddata_mouse_cmd(0xfa); - - ps2_report_coordinates(dev, 1); - break; - - case 0xf2: /* read ID */ - keyboard_at_adddata_mouse_cmd(0xfa); - if (dev->flags & FLAG_INTMODE) - keyboard_at_adddata_mouse_cmd((dev->flags & FLAG_5BTN) ? 0x04 : 0x03); - else - keyboard_at_adddata_mouse_cmd(0x00); - break; - - case 0xf3: /* set command mode */ - dev->flags |= FLAG_CTRLDAT; - keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */ - break; - - case 0xf4: /* enable */ - dev->flags |= FLAG_ENABLED; - mouse_scan = 1; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xf5: /* disable */ - dev->flags &= ~FLAG_ENABLED; - mouse_scan = 0; - keyboard_at_adddata_mouse_cmd(0xfa); - break; - - case 0xf6: /* set defaults */ - case 0xff: /* reset */ -mouse_reset: - dev->mode = MODE_STREAM; - dev->flags &= 0x88; - mouse_scan = 1; - keyboard_at_mouse_reset(); - keyboard_at_adddata_mouse_cmd(0xfa); - if (dev->command == 0xff) { - keyboard_at_adddata_mouse_cmd(0xaa); - keyboard_at_adddata_mouse_cmd(0x00); - } - break; - - default: - keyboard_at_adddata_mouse_cmd(0xfe); - } - } - - if (dev->flags & FLAG_INTELLI) { - for (temp = 0; temp < 5; temp++) - dev->last_data[temp] = dev->last_data[temp + 1]; - - dev->last_data[5] = val; - - if ((dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) && - (dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0x64) && - (dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50)) - dev->flags |= FLAG_INTMODE; - - if ((dev->flags & FLAG_INTMODE) && (dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) && - (dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0xc8) && - (dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50)) - dev->flags |= FLAG_5BTN; - } -} - -static int -ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - if (!x && !y && !z && (b == dev->b)) - return (0xff); - -#if 0 - if (!(dev->flags & FLAG_ENABLED)) - return(0xff); -#endif - - if (!mouse_scan) - return (0xff); - - dev->x += x; - dev->y -= y; - dev->z -= z; -#if 0 - if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) { -#else - if ((dev->mode == MODE_STREAM) && (keyboard_at_mouse_pos() < 13)) { -#endif - dev->b = b; - - ps2_report_coordinates(dev, 0); - } - - return (0); -} - -/* - * Initialize the device for use by the user. - * - * We also get called from the various machines. - */ -void * -mouse_ps2_init(const device_t *info) -{ - mouse_t *dev; - int i; - - dev = (mouse_t *) malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - - dev->mode = MODE_STREAM; - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_INTELLI; - - if (i == 4) - i = 3; - - /* Hook into the general AT Keyboard driver. */ - keyboard_at_set_mouse(ps2_write, dev); - - mouse_ps2_log("%s: buttons=%d\n", dev->name, i); - - /* Tell them how many buttons we have. */ - mouse_set_buttons(i); - - /* Return our private data to the I/O layer. */ - return (dev); -} - -static void -ps2_close(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - /* Unhook from the general AT Keyboard driver. */ - keyboard_at_set_mouse(NULL, NULL); - - free(dev); -} - -static const device_config_t ps2_config[] = { - // clang-format off - { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Two", .value = 2 }, - { .description = "Three", .value = 3 }, - { .description = "Wheel", .value = 4 }, - { .description = "Five + Wheel", .value = 5 }, - { .description = "" } - } - }, - { - .name = "", .description = "", .type = CONFIG_END - } - // clang-format on -}; - -const device_t mouse_ps2_device = { - .name = "Standard PS/2 Mouse", - .internal_name = "ps2", - .flags = DEVICE_PS2, - .local = MOUSE_TYPE_PS2, - .init = mouse_ps2_init, - .close = ps2_close, - .reset = NULL, - { .poll = ps2_poll }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ps2_config -}; diff --git a/src/mem/mem - Cópia.c b/src/mem/mem - Cópia.c deleted file mode 100644 index a8d9e994d..000000000 --- a/src/mem/mem - Cópia.c +++ /dev/null @@ -1,3092 +0,0 @@ -/* - * 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. - * - * Memory handling and MMU. - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/version.h> -#include "cpu.h" -#include "x86_ops.h" -#include "x86.h" -#include <86box/machine.h> -#include <86box/m_xt_xi8088.h> -#include <86box/config.h> -#include <86box/io.h> -#include <86box/mem.h> -#include <86box/plat.h> -#include <86box/rom.h> -#include <86box/gdbstub.h> -#ifdef USE_DYNAREC -# include "codegen_public.h" -#else -# ifdef USE_NEW_DYNAREC -# define PAGE_MASK_SHIFT 6 -# else -# define PAGE_MASK_INDEX_MASK 3 -# define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_SHIFT 4 -# endif -# define PAGE_MASK_MASK 63 -#endif -#if (!defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) -# define BLOCK_PC_INVALID 0xffffffff -# define BLOCK_INVALID 0 -#endif - -mem_mapping_t ram_low_mapping, /* 0..640K mapping */ - ram_mid_mapping, /* 640..1024K mapping */ - ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */ - ram_remapped_mapping, /* 640..1024K mapping */ - ram_remapped_mapping2, /* 640..1024K second mapping, for SiS 471 mode */ - ram_high_mapping, /* 1024K+ mapping */ - ram_2gb_mapping, /* 1024M+ mapping */ - ram_split_mapping, - bios_mapping, - bios_high_mapping; - -page_t *pages, /* RAM page table */ - **page_lookup; /* pagetable lookup */ -uint32_t pages_sz; /* #pages in table */ - -uint8_t *ram, *ram2; /* the virtual RAM */ -uint8_t page_ff[4096]; -uint32_t rammask; -uint32_t addr_space_size; - -uint8_t *rom; /* the virtual ROM */ -uint32_t biosmask, biosaddr; - -uint32_t pccache; -uint8_t *pccache2; - -int readlnext; -int readlookup[256]; -uintptr_t *readlookup2; -uintptr_t old_rl2; -uint8_t uncached = 0; -int writelnext; -int writelookup[256]; -uintptr_t *writelookup2; - -uint32_t mem_logical_addr; - -int shadowbios = 0, - shadowbios_write; -int readlnum = 0, - writelnum = 0; -int cachesize = 256; - -uint32_t get_phys_virt, - get_phys_phys; - -int mem_a20_key = 0, - mem_a20_alt = 0, - mem_a20_state = 0; - -int mmuflush = 0; -int mmu_perm = 4; - -#ifdef USE_NEW_DYNAREC -uint64_t *byte_dirty_mask; -uint64_t *byte_code_present_mask; - -uint32_t purgable_page_list_head = 0; -int purgeable_page_count = 0; -#endif - -uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ - -/* FIXME: re-do this with a 'mem_ops' struct. */ -static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ -static uint8_t *readlookupp; -static uint8_t *writelookupp; -static mem_mapping_t *base_mapping, *last_mapping; -static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; -static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; -static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO]; -static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO]; -static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; -static mem_state_t _mem_state[MEM_MAPPINGS_NO]; -static uint32_t remap_start_addr, remap_start_addr2; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -static size_t ram_size = 0, ram2_size = 0; -#else -static size_t ram_size = 0; -#endif - -#ifdef ENABLE_MEM_LOG -int mem_do_log = ENABLE_MEM_LOG; - -static void -mem_log(const char *fmt, ...) -{ - va_list ap; - - if (mem_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define mem_log(fmt, ...) -#endif - -int -mem_addr_is_ram(uint32_t addr) -{ - mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || - (mapping == &ram_mid_mapping2) || (mapping == &ram_remapped_mapping); -} - -void -resetreadlookup(void) -{ - int c; - - /* Initialize the page lookup table. */ - memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); - - /* Initialize the tables for lower (<= 1024K) RAM. */ - for (c = 0; c < 256; c++) { - readlookup[c] = 0xffffffff; - writelookup[c] = 0xffffffff; - } - - /* Initialize the tables for high (> 1024K) RAM. */ - memset(readlookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(readlookupp, 0x04, (1 << 20) * sizeof(uint8_t)); - - memset(writelookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(writelookupp, 0x04, (1 << 20) * sizeof(uint8_t)); - - readlnext = 0; - writelnext = 0; - pccache = 0xffffffff; - high_page = 0; -} - -void -flushmmucache(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; - writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; - writelookup[c] = 0xffffffff; - } - } - mmuflush++; - - pccache = (uint32_t) 0xffffffff; - pccache2 = (uint8_t *) 0xffffffff; - -#ifdef USE_DYNAREC - codegen_flush(); -#endif -} - -void -flushmmucache_nopc(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; - writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; - writelookup[c] = 0xffffffff; - } - } -} - -void -mem_flush_write_page(uint32_t addr, uint32_t virt) -{ - page_t *page_target = &pages[addr >> 12]; - int c; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif - - for (c = 0; c < 256; c++) { - if (writelookup[c] != (int) 0xffffffff) { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - uintptr_t target = (uintptr_t) &ram[(uintptr_t) (addr & ~0xfff) - (virt & ~0xfff)]; -#else - a = (uintptr_t) (addr & ~0xfff) - (virt & ~0xfff); - uintptr_t target; - - if ((addr & ~0xfff) >= (1 << 30)) - target = (uintptr_t) &ram2[a - (1 << 30)]; - else - target = (uintptr_t) &ram[a]; -#endif - - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { - writelookup2[writelookup[c]] = LOOKUP_INV; - page_lookup[writelookup[c]] = NULL; - writelookup[c] = 0xffffffff; - } - } - } -} - -#define mmutranslate_read(addr) mmutranslatereal(addr, 0) -#define mmutranslate_write(addr) mmutranslatereal(addr, 1) -#define rammap(x) ((uint32_t *) (_mem_exec[(x) >> MEM_GRANULARITY_BITS]))[((x) >> 2) & MEM_GRANULARITY_QMASK] -#define rammap64(x) ((uint64_t *) (_mem_exec[(x) >> MEM_GRANULARITY_BITS]))[((x) >> 3) & MEM_GRANULARITY_PMASK] - -static __inline uint64_t -mmutranslatereal_normal(uint32_t addr, int rw) -{ - uint32_t temp, temp2, temp3; - uint32_t addr2; - - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - if (!(temp & 1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; - } - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - - return 0xffffffffffffffffULL; - } - - mmu_perm = temp & 4; - rammap(addr2) |= (rw ? 0x60 : 0x20); - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20); - - return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); -} - -static __inline uint64_t -mmutranslatereal_pae(uint32_t addr, int rw) -{ - uint64_t temp, temp2, temp3, temp4; - uint64_t addr2, addr3, addr4; - - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - addr2 = (cr3 & ~0x1f) + ((addr >> 27) & 0x18); - temp = temp2 = rammap64(addr2) & 0x000000ffffffffffULL; - if (!(temp & 1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; - } - - addr3 = (temp & ~0xfffULL) + ((addr >> 18) & 0xff8); - temp = temp4 = rammap64(addr3) & 0x000000ffffffffffULL; - temp3 = temp & temp2; - if (!(temp & 1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; - } - - if (temp & 0x80) { - /*2MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - - return 0xffffffffffffffffULL; - } - mmu_perm = temp & 4; - rammap64(addr3) |= (rw ? 0x60 : 0x20); - - return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; - } - - addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8); - temp = rammap64(addr4) & 0x000000ffffffffffULL; - temp3 = temp & temp4; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; - } - - mmu_perm = temp & 4; - rammap64(addr3) |= 0x20; - rammap64(addr4) |= (rw ? 0x60 : 0x20); - - return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL; -} - -uint64_t -mmutranslatereal(uint32_t addr, int rw) -{ - /* Fast path to return invalid without any call if an exception has occurred beforehand. */ - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - if (cr4 & CR4_PAE) - return mmutranslatereal_pae(addr, rw); - else - return mmutranslatereal_normal(addr, rw); -} - -/* This is needed because the old recompiler calls this to check for page fault. */ -uint32_t -mmutranslatereal32(uint32_t addr, int rw) -{ - /* Fast path to return invalid without any call if an exception has occurred beforehand. */ - if (cpu_state.abrt) - return (uint32_t) 0xffffffffffffffffULL; - - return (uint32_t) mmutranslatereal(addr, rw); -} - -static __inline uint64_t -mmutranslate_noabrt_normal(uint32_t addr, int rw) -{ - uint32_t temp, temp2, temp3; - uint32_t addr2; - - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - - if (!(temp & 1)) - return 0xffffffffffffffffULL; - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) - return 0xffffffffffffffffULL; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) - return 0xffffffffffffffffULL; - - return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); -} - -static __inline uint64_t -mmutranslate_noabrt_pae(uint32_t addr, int rw) -{ - uint64_t temp, temp2, temp3, temp4; - uint64_t addr2, addr3, addr4; - - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - addr2 = (cr3 & ~0x1f) + ((addr >> 27) & 0x18); - temp = temp2 = rammap64(addr2) & 0x000000ffffffffffULL; - - if (!(temp & 1)) - return 0xffffffffffffffffULL; - - addr3 = (temp & ~0xfffULL) + ((addr >> 18) & 0xff8); - temp = temp4 = rammap64(addr3) & 0x000000ffffffffffULL; - temp3 = temp & temp2; - - if (!(temp & 1)) - return 0xffffffffffffffffULL; - - if (temp & 0x80) { - /*2MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) - return 0xffffffffffffffffULL; - - return ((temp & ~0x1fffffULL) + (addr & 0x1fffff)) & 0x000000ffffffffffULL; - } - - addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8); - temp = rammap64(addr4) & 0x000000ffffffffffULL; - ; - temp3 = temp & temp4; - - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) - return 0xffffffffffffffffULL; - - return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL; -} - -uint64_t -mmutranslate_noabrt(uint32_t addr, int rw) -{ - /* Fast path to return invalid without any call if an exception has occurred beforehand. */ - if (cpu_state.abrt) - return 0xffffffffffffffffULL; - - if (cr4 & CR4_PAE) - return mmutranslate_noabrt_pae(addr, rw); - else - return mmutranslate_noabrt_normal(addr, rw); -} - -void -mmu_invalidate(uint32_t addr) -{ - flushmmucache_cr3(); -} - -uint8_t -mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len) -{ - if (addr < start) - return 0; - else if (addr >= (start + len)) - return 0; - else - return 1; -} - -uint32_t -mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) -{ - uint32_t mask = len - 1; - - return chunk_start + (addr & mask); -} - -void -addreadlookup(uint32_t virt, uint32_t phys) -{ -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif - - if (virt == 0xffffffff) - return; - - if (readlookup2[virt >> 12] != (uintptr_t) LOOKUP_INV) - return; - - if (readlookup[readlnext] != (int) 0xffffffff) { - if ((readlookup[readlnext] == ((es + DI) >> 12)) || (readlookup[readlnext] == ((es + EDI) >> 12))) - uncached = 1; - readlookup2[readlookup[readlnext]] = LOOKUP_INV; - } - -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - readlookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; -#else - a = ((uint32_t) (phys & ~0xfff) - (uint32_t) (virt & ~0xfff)); - - if ((phys & ~0xfff) >= (1 << 30)) - readlookup2[virt >> 12] = (uintptr_t) &ram2[a - (1 << 30)]; - else - readlookup2[virt >> 12] = (uintptr_t) &ram[a]; -#endif - readlookupp[virt >> 12] = mmu_perm; - - readlookup[readlnext++] = virt >> 12; - readlnext &= (cachesize - 1); - - cycles -= 9; -} - -void -addwritelookup(uint32_t virt, uint32_t phys) -{ -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif - - if (virt == 0xffffffff) - return; - - if (page_lookup[virt >> 12]) - return; - - if (writelookup[writelnext] != -1) { - page_lookup[writelookup[writelnext]] = NULL; - writelookup2[writelookup[writelnext]] = LOOKUP_INV; - } - -#ifdef USE_NEW_DYNAREC -# ifdef USE_DYNAREC - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) { -# else - if (pages[phys >> 12].block) { -# endif -#else -# ifdef USE_DYNAREC - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) { -# else - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) { -# endif -#endif - page_lookup[virt >> 12] = &pages[phys >> 12]; - page_lookupp[virt >> 12] = mmu_perm; - } else { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; -#else - a = ((uint32_t) (phys & ~0xfff) - (uint32_t) (virt & ~0xfff)); - - if ((phys & ~0xfff) >= (1 << 30)) - writelookup2[virt >> 12] = (uintptr_t) &ram2[a - (1 << 30)]; - else - writelookup2[virt >> 12] = (uintptr_t) &ram[a]; -#endif - } - writelookupp[virt >> 12] = mmu_perm; - - writelookup[writelnext++] = virt >> 12; - writelnext &= (cachesize - 1); - - cycles -= 9; -} - -uint8_t * -getpccache(uint32_t a) -{ - uint64_t a64 = (uint64_t) a; - uint32_t a2; - - a2 = a; - - if (cr0 >> 31) { - a64 = mmutranslate_read(a64); - - if (a64 == 0xffffffffffffffffULL) - return ram; - } - a64 &= rammask; - - if (_mem_exec[a64 >> MEM_GRANULARITY_BITS]) { - if (is286) { - if (read_mapping[a64 >> MEM_GRANULARITY_BITS] && (read_mapping[a64 >> MEM_GRANULARITY_BITS]->flags & MEM_MAPPING_ROM_WS)) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; - } - - return &_mem_exec[a64 >> MEM_GRANULARITY_BITS][(uintptr_t) (a64 & MEM_GRANULARITY_PAGE) - (uintptr_t) (a2 & ~0xfff)]; - } - - mem_log("Bad getpccache %08X%08X\n", (uint32_t) (a64 >> 32), (uint32_t) (a64 & 0xffffffffULL)); - - return (uint8_t *) &ff_pccache; -} - -uint8_t -read_mem_b(uint32_t addr) -{ - mem_mapping_t *map; - uint8_t ret = 0xff; - int old_cycles = cycles; - - mem_logical_addr = addr; - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_b) - ret = map->read_b(addr, map->p); - - resub_cycles(old_cycles); - - return ret; -} - -uint16_t -read_mem_w(uint32_t addr) -{ - mem_mapping_t *map; - uint16_t ret = 0xffff; - int old_cycles = cycles; - - mem_logical_addr = addr; - addr &= rammask; - - if (addr & 1) - ret = read_mem_b(addr) | (read_mem_b(addr + 1) << 8); - else { - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->read_w) - ret = map->read_w(addr, map->p); - else if (map && map->read_b) - ret = map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); - } - - resub_cycles(old_cycles); - - return ret; -} - -void -write_mem_b(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map; - int old_cycles = cycles; - - mem_logical_addr = addr; - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->write_b) - map->write_b(addr, val, map->p); - - resub_cycles(old_cycles); -} - -void -write_mem_w(uint32_t addr, uint16_t val) -{ - mem_mapping_t *map; - int old_cycles = cycles; - - mem_logical_addr = addr; - addr &= rammask; - - if (addr & 1) { - write_mem_b(addr, val); - write_mem_b(addr + 1, val >> 8); - } else { - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_w) - map->write_w(addr, val, map->p); - else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - } - } - } - - resub_cycles(old_cycles); -} - -uint8_t -readmembl(uint32_t addr) -{ - mem_mapping_t *map; - uint64_t a; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RB ] %08X\n", addr); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - - addr64 = (uint64_t) addr; - mem_logical_addr = addr; - - high_page = 0; - - if (cr0 >> 31) { - a = mmutranslate_read(addr); - addr64 = (uint32_t) a; - - if (a > 0xffffffffULL) - return 0xff; - } - addr = (uint32_t) (addr64 & rammask); - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_b) - return map->read_b(addr, map->p); - - return 0xff; -} - -void -writemembl(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map; - uint64_t a; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WB ] %08X = %02X\n", addr, val); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); - - addr64 = (uint64_t) addr; - mem_logical_addr = addr; - - high_page = 0; - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_b) { - page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - a = mmutranslate_write(addr); - addr64 = (uint32_t) a; - - if (a > 0xffffffffULL) - return; - } - addr = (uint32_t) (addr64 & rammask); - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->write_b) - map->write_b(addr, val, map->p); -} - -/* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ -uint8_t -readmembl_no_mmut(uint32_t addr, uint32_t a64) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RBN] %08X\n", addr); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - - mem_logical_addr = addr; - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xff; - - addr = a64 & rammask; - } else - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_b) - return map->read_b(addr, map->p); - - return 0xff; -} - -/* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */ -void -writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WBN] %08X = %02X\n", addr, val); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); - - mem_logical_addr = addr; - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_b) { - page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - - addr = a64 & rammask; - } else - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->write_b) - map->write_b(addr, val, map->p); -} - -uint16_t -readmemwl(uint32_t addr) -{ - mem_mapping_t *map; - int i; - uint64_t a; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RW ] %08X\n", addr); - - addr64a[0] = addr; - addr64a[1] = addr + 1; - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - for (i = 0; i < 2; i++) { - a = mmutranslate_read(addr + i); - addr64a[i] = (uint32_t) a; - - if (a > 0xffffffffULL) - return 0xffff; - } - } - - return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; - return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } - } - - if (cr0 >> 31) { - a = mmutranslate_read(addr); - addr64a[0] = (uint32_t) a; - - if (a > 0xffffffffULL) - return 0xffff; - } else - addr64a[0] = (uint64_t) addr; - - addr = addr64a[0] & rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->read_w) - return map->read_w(addr, map->p); - - if (map && map->read_b) { - return map->read_b(addr, map->p) | ((uint16_t) (map->read_b(addr + 1, map->p)) << 8); - } - - return 0xffff; -} - -void -writememwl(uint32_t addr, uint16_t val) -{ - mem_mapping_t *map; - int i; - uint64_t a; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WW ] %08X = %04X\n", addr, val); - - addr64a[0] = addr; - addr64a[1] = addr + 1; - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - for (i = 0; i < 2; i++) { - /* Do not translate a page that has a valid lookup, as that is by definition valid - and the whole purpose of the lookup is to avoid repeat identical translations. */ - if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - a = mmutranslate_write(addr + i); - addr64a[i] = (uint32_t) a; - - if (a > 0xffffffffULL) - return; - } - } - } - - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writemembl_no_mmut(addr, addr64a[0], val); - writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); - return; - } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; - *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { - page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); - mmu_perm = page_lookupp[addr >> 12]; - return; - } - - if (cr0 >> 31) { - a = mmutranslate_write(addr); - addr64a[0] = (uint32_t) a; - - if (a > 0xffffffffULL) - return; - } - - addr = addr64a[0] & rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->write_w) { - map->write_w(addr, val, map->p); - return; - } - - if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - return; - } -} - -/* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */ -uint16_t -readmemwl_no_mmut(uint32_t addr, uint32_t *a64) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RWN] %08X\n", addr); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffff; - } - - return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; - return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } - } - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffff; - - addr = (uint32_t) (a64[0] & rammask); - } else - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->read_w) - return map->read_w(addr, map->p); - - if (map && map->read_b) { - return map->read_b(addr, map->p) | ((uint16_t) (map->read_b(addr + 1, map->p)) << 8); - } - - return 0xffff; -} - -/* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */ -void -writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WWN] %08X = %04X\n", addr, val); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - } - - writemembl_no_mmut(addr, a64[0], val); - writemembl_no_mmut(addr + 1, a64[1], val >> 8); - return; - } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; - *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { - mmu_perm = page_lookupp[addr >> 12]; - page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - - addr = (uint32_t) (a64[0] & rammask); - } else - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->write_w) { - map->write_w(addr, val, map->p); - return; - } - - if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - return; - } -} - -uint32_t -readmemll(uint32_t addr) -{ - mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RL ] %08X\n", addr); - - for (i = 0; i < 4; i++) - addr64a[i] = (uint64_t) (addr + i); - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - for (i = 0; i < 4; i++) { - if (i == 0) { - a = mmutranslate_read(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_read(addr + 3); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - - if (a > 0xffffffffULL) - return 0xffff; - } - } - - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; - return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } - } - - if (cr0 >> 31) { - a = mmutranslate_read(addr); - addr64a[0] = (uint32_t) a; - - if (a > 0xffffffffULL) - return 0xffffffff; - } - - addr = addr64a[0] & rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->read_l) - return map->read_l(addr, map->p); - - if (map && map->read_w) - return map->read_w(addr, map->p) | ((uint32_t) (map->read_w(addr + 2, map->p)) << 16); - - if (map && map->read_b) - return map->read_b(addr, map->p) | ((uint32_t) (map->read_b(addr + 1, map->p)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->p)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); - - return 0xffffffff; -} - -void -writememll(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WL ] %08X = %08X\n", addr, val); - - for (i = 0; i < 4; i++) - addr64a[i] = (uint64_t) (addr + i); - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - for (i = 0; i < 4; i++) { - /* Do not translate a page that has a valid lookup, as that is by definition valid - and the whole purpose of the lookup is to avoid repeat identical translations. */ - if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if (i == 0) { - a = mmutranslate_write(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_write(addr + 3); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - - if (a > 0xffffffffULL) - return; - } - } - } - - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writememwl_no_mmut(addr, &(addr64a[0]), val); - writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); - return; - } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; - *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; - page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - a = mmutranslate_write(addr); - addr64a[0] = (uint32_t) a; - - if (a > 0xffffffffULL) - return; - } - - addr = addr64a[0] & rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WL ] map = %08X\n", map); - - if (map && map->write_l) { - map->write_l(addr, val, map->p); - return; - } - if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - return; - } - if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - return; - } -} - -/* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */ -uint32_t -readmemll_no_mmut(uint32_t addr, uint32_t *a64) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RLN] %08X\n", addr); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffffffff; - } - - return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; - return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } - } - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffffffff; - - addr = (uint32_t) (a64[0] & rammask); - } else - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->read_l) - return map->read_l(addr, map->p); - - if (map && map->read_w) - return map->read_w(addr, map->p) | ((uint32_t) (map->read_w(addr + 2, map->p)) << 16); - - if (map && map->read_b) - return map->read_b(addr, map->p) | ((uint32_t) (map->read_b(addr + 1, map->p)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->p)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); - - return 0xffffffff; -} - -/* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ -void -writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) -{ - mem_mapping_t *map; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WLN] %08X = %08X\n", addr, val); - - GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - } - - writememwl_no_mmut(addr, &(a64[0]), val); - writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); - return; - } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; - *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; - page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - - addr = (uint32_t) (a64[0] & rammask); - } else - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->write_l) { - map->write_l(addr, val, map->p); - return; - } - if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - return; - } - if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - return; - } -} - -uint64_t -readmemql(uint32_t addr) -{ - mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[RQ ] %08X\n", addr); - - for (i = 0; i < 8; i++) - addr64a[i] = (uint64_t) (addr + i); - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { - for (i = 0; i < 8; i++) { - if (i == 0) { - a = mmutranslate_read(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_read(addr + 7); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - - if (a > 0xffffffffULL) - return 0xffff; - } - } - - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; - return *(uint64_t *) (readlookup2[addr >> 12] + addr); - } - } - - if (cr0 >> 31) { - a = mmutranslate_read(addr); - addr64a[0] = (uint32_t) a; - - if (a > 0xffffffffULL) - return 0xffffffffffffffffULL; - } - - addr = addr64a[0] & rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_l) - return map->read_l(addr, map->p) | ((uint64_t) map->read_l(addr + 4, map->p) << 32); - - return readmemll(addr) | ((uint64_t) readmemll(addr + 4) << 32); -} - -void -writememql(uint32_t addr, uint64_t val) -{ - mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; - - if ((addr >= 0xec000000) && (addr <= 0xecffffff)) - pclog("[WQ ] %08X = %016" PRIX64 "\n", addr, val); - - for (i = 0; i < 8; i++) - addr64a[i] = (uint64_t) (addr + i); - GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); - - mem_logical_addr = addr; - - high_page = 0; - - if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { - for (i = 0; i < 8; i++) { - /* Do not translate a page that has a valid lookup, as that is by definition valid - and the whole purpose of the lookup is to avoid repeat identical translations. */ - if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if (i == 0) { - a = mmutranslate_write(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_write(addr + 7); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - - if (addr64a[i] > 0xffffffffULL) - return; - } - } - } - - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writememll_no_mmut(addr, addr64a, val); - writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); - return; - } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; - *(uint64_t *) (writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; - page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); - page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); - return; - } - - if (cr0 >> 31) { - addr64a[0] = mmutranslate_write(addr); - if (addr64a[0] > 0xffffffffULL) - return; - } - - addr = addr64a[0] & rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map && map->write_l) { - map->write_l(addr, val, map->p); - map->write_l(addr + 4, val >> 32, map->p); - return; - } - if (map && map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - map->write_w(addr + 4, val >> 32, map->p); - map->write_w(addr + 6, val >> 48, map->p); - return; - } - if (map && map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - map->write_b(addr + 4, val >> 32, map->p); - map->write_b(addr + 5, val >> 40, map->p); - map->write_b(addr + 6, val >> 48, map->p); - map->write_b(addr + 7, val >> 56, map->p); - return; - } -} - -void -do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) -{ - int i, cond = 1; - uint32_t last_addr = addr + (num - 1); - uint64_t a = 0x0000000000000000ULL; - - for (i = 0; i < num; i++) - a64[i] = (uint64_t) addr; - - for (i = 0; i < num; i++) { - if (cr0 >> 31) { - if (write && ((i == 0) || !(addr & 0xfff))) - cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); - - if (cond) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal(addr, write); - a64[i] = (uint32_t) a; - - high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); - } else if (!(addr & 0xfff)) { - a = mmutranslatereal(last_addr, write); - a64[i] = (uint32_t) a; - - high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); - - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else - mmu_perm = page_lookupp[addr >> 12]; - } - - addr++; - } -} - -uint8_t -mem_readb_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint8_t ret = 0xff; - - mem_logical_addr = 0xffffffff; - - if (map) { - if (map->exec) - ret = map->exec[(addr - map->base) & map->mask]; - else if (map->read_b) - ret = map->read_b(addr, map->p); - } - - return ret; -} - -uint16_t -mem_readw_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint16_t ret, *p; - - mem_logical_addr = 0xffffffff; - - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { - p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); - ret = *p; - } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) - ret = map->read_w(addr, map->p); - else { - ret = mem_readb_phys(addr + 1) << 8; - ret |= mem_readb_phys(addr); - } - - return ret; -} - -uint32_t -mem_readl_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint32_t ret, *p; - - mem_logical_addr = 0xffffffff; - - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { - p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); - ret = *p; - } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) - ret = map->read_l(addr, map->p); - else { - ret = mem_readw_phys(addr + 2) << 16; - ret |= mem_readw_phys(addr); - } - - return ret; -} - -void -mem_read_phys(void *dest, uint32_t addr, int transfer_size) -{ - uint8_t *pb; - uint16_t *pw; - uint32_t *pl; - - if (transfer_size == 4) { - pl = (uint32_t *) dest; - *pl = mem_readl_phys(addr); - } else if (transfer_size == 2) { - pw = (uint16_t *) dest; - *pw = mem_readw_phys(addr); - } else if (transfer_size == 1) { - pb = (uint8_t *) dest; - *pb = mem_readb_phys(addr); - } -} - -void -mem_writeb_phys(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - - mem_logical_addr = 0xffffffff; - - if (map) { - if (map->exec) - map->exec[(addr - map->base) & map->mask] = val; - else if (map->write_b) - map->write_b(addr, val, map->p); - } -} - -void -mem_writew_phys(uint32_t addr, uint16_t val) -{ - mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint16_t *p; - - mem_logical_addr = 0xffffffff; - - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) { - p = (uint16_t *) &(map->exec[(addr - map->base) & map->mask]); - *p = val; - } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) - map->write_w(addr, val, map->p); - else { - mem_writeb_phys(addr, val & 0xff); - mem_writeb_phys(addr + 1, (val >> 8) & 0xff); - } -} - -void -mem_writel_phys(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS]; - uint32_t *p; - - mem_logical_addr = 0xffffffff; - - if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) { - p = (uint32_t *) &(map->exec[(addr - map->base) & map->mask]); - *p = val; - } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) - map->write_l(addr, val, map->p); - else { - mem_writew_phys(addr, val & 0xffff); - mem_writew_phys(addr + 2, (val >> 16) & 0xffff); - } -} - -void -mem_write_phys(void *src, uint32_t addr, int transfer_size) -{ - uint8_t *pb; - uint16_t *pw; - uint32_t *pl; - - if (transfer_size == 4) { - pl = (uint32_t *) src; - mem_writel_phys(addr, *pl); - } else if (transfer_size == 2) { - pw = (uint16_t *) src; - mem_writew_phys(addr, *pw); - } else if (transfer_size == 1) { - pb = (uint8_t *) src; - mem_writeb_phys(addr, *pb); - } -} - -uint8_t -mem_read_ram(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read B %02X from %08X\n", ram[addr], addr); -#endif - - if (is286) - addreadlookup(mem_logical_addr, addr); - - return ram[addr]; -} - -uint16_t -mem_read_ramw(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read W %04X from %08X\n", *(uint16_t *) &ram[addr], addr); -#endif - - if (is286) - addreadlookup(mem_logical_addr, addr); - - return *(uint16_t *) &ram[addr]; -} - -uint32_t -mem_read_raml(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read L %08X from %08X\n", *(uint32_t *) &ram[addr], addr); -#endif - - if (is286) - addreadlookup(mem_logical_addr, addr); - - return *(uint32_t *) &ram[addr]; -} - -uint8_t -mem_read_ram_2gb(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read B %02X from %08X\n", ram[addr], addr); -#endif - - addreadlookup(mem_logical_addr, addr); - - return ram2[addr - (1 << 30)]; -} - -uint16_t -mem_read_ram_2gbw(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read W %04X from %08X\n", *(uint16_t *) &ram[addr], addr); -#endif - - addreadlookup(mem_logical_addr, addr); - - return *(uint16_t *) &ram2[addr - (1 << 30)]; -} - -uint32_t -mem_read_ram_2gbl(uint32_t addr, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Read L %08X from %08X\n", *(uint32_t *) &ram[addr], addr); -#endif - - addreadlookup(mem_logical_addr, addr); - - return *(uint32_t *) &ram2[addr - (1 << 30)]; -} - -#ifdef USE_NEW_DYNAREC -static inline int -page_index(page_t *p) -{ - return ((uintptr_t) p - (uintptr_t) pages) / sizeof(page_t); -} - -void -page_add_to_evict_list(page_t *p) -{ - pages[purgable_page_list_head].evict_prev = page_index(p); - p->evict_next = purgable_page_list_head; - p->evict_prev = 0; - purgable_page_list_head = pages[purgable_page_list_head].evict_prev; - purgeable_page_count++; -} - -void -page_remove_from_evict_list(page_t *p) -{ - if (!page_in_evict_list(p)) - fatal("page_remove_from_evict_list: not in evict list!\n"); - if (p->evict_prev) - pages[p->evict_prev].evict_next = p->evict_next; - else - purgable_page_list_head = p->evict_next; - if (p->evict_next) - pages[p->evict_next].evict_prev = p->evict_prev; - p->evict_prev = EVICT_NOT_IN_LIST; - purgeable_page_count--; -} - -void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t) 1 << (addr & PAGE_BYTE_MASK_MASK); - - p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - -void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t) 1 << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); - *(uint16_t *) &p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { - p->byte_dirty_mask[byte_offset + 1] |= 1; - if ((p->byte_code_present_mask[byte_offset + 1] & 1) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } else - byte_mask |= (byte_mask << 1); - - p->byte_dirty_mask[byte_offset] |= byte_mask; - - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - -void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t) 0xf << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); - *(uint32_t *) &p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK - 3)) { - uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); - - p->byte_dirty_mask[byte_offset + 1] |= byte_mask_2; - if ((p->byte_code_present_mask[byte_offset + 1] & byte_mask_2) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } - } -} -#else -void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - p->mem[addr & 0xfff] = val; - } -} - -void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *) &p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint16_t *) &p->mem[addr & 0xfff] = val; - } -} - -void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) -{ - if (p == NULL) - return; - -# ifdef USE_DYNAREC - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff]) || codegen_in_recompile) { -# else - if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *) &p->mem[addr & 0xfff])) { -# endif - uint64_t mask = (uint64_t) 1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint32_t *) &p->mem[addr & 0xfff] = val; - } -} -#endif - -void -mem_write_ram(uint32_t addr, uint8_t val, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Write B %02X to %08X\n", val, addr); -#endif - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[addr >> 12]); - } else - ram[addr] = val; -} - -void -mem_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Write W %04X to %08X\n", val, addr); -#endif - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[addr >> 12]); - } else - *(uint16_t *) &ram[addr] = val; -} - -void -mem_write_raml(uint32_t addr, uint32_t val, void *priv) -{ -#ifdef ENABLE_MEM_LOG - if ((addr >= 0xa0000) && (addr <= 0xbffff)) - mem_log("Write L %08X to %08X\n", val, addr); -#endif - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[addr >> 12]); - } else - *(uint32_t *) &ram[addr] = val; -} - -static uint8_t -mem_read_remapped(uint32_t addr, void *priv) -{ - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) - addreadlookup(mem_logical_addr, addr); - return ram[addr]; -} - -static uint16_t -mem_read_remappedw(uint32_t addr, void *priv) -{ - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *) &ram[addr]; -} - -static uint32_t -mem_read_remappedl(uint32_t addr, void *priv) -{ - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *) &ram[addr]; -} - -static uint8_t -mem_read_remapped2(uint32_t addr, void *priv) -{ - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) - addreadlookup(mem_logical_addr, addr); - return ram[addr]; -} - -static uint16_t -mem_read_remappedw2(uint32_t addr, void *priv) -{ - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *) &ram[addr]; -} - -static uint32_t -mem_read_remappedl2(uint32_t addr, void *priv) -{ - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *) &ram[addr]; -} - -static void -mem_write_remapped(uint32_t addr, uint8_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); - } else - ram[addr] = val; -} - -static void -mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); - } else - *(uint16_t *) &ram[addr] = val; -} - -static void -mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); - } else - *(uint32_t *) &ram[addr] = val; -} - -static void -mem_write_remapped2(uint32_t addr, uint8_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); - } else - ram[addr] = val; -} - -static void -mem_write_remappedw2(uint32_t addr, uint16_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); - } else - *(uint16_t *) &ram[addr] = val; -} - -static void -mem_write_remappedl2(uint32_t addr, uint32_t val, void *priv) -{ - uint32_t oldaddr = addr; - addr = 0xD0000 + (addr - remap_start_addr2); - if (is286) { - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); - } else - *(uint32_t *) &ram[addr] = val; -} - -void -mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) -{ -#ifdef USE_NEW_DYNAREC - page_t *p; - - start_addr &= ~PAGE_MASK_MASK; - end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - - for (; start_addr <= end_addr; start_addr += 0x1000) { - if ((start_addr >> 12) >= pages_sz) - continue; - - p = &pages[start_addr >> 12]; - if (p) { - p->dirty_mask = 0xffffffffffffffffULL; - - if (p->byte_dirty_mask) - memset(p->byte_dirty_mask, 0xff, 64 * sizeof(uint64_t)); - - if (!page_in_evict_list(p)) - page_add_to_evict_list(p); - } - } -#else - uint32_t cur_addr; - start_addr &= ~PAGE_MASK_MASK; - end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - - for (; start_addr <= end_addr; start_addr += 0x1000) { - /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses - may crash the emulator. */ - cur_addr = (start_addr >> 12); - if (cur_addr < pages_sz) - memset(pages[cur_addr].dirty_mask, 0xff, sizeof(pages[cur_addr].dirty_mask)); - } -#endif -} - -static __inline int -mem_mapping_access_allowed(uint32_t flags, uint16_t access) -{ - int ret = 0; - - if (!(access & ACCESS_DISABLED)) { - if (access & ACCESS_CACHE) - ret = (flags & MEM_MAPPING_CACHE); - else if (access & ACCESS_SMRAM) - ret = (flags & MEM_MAPPING_SMRAM); - else if (!(access & ACCESS_INTERNAL)) { - if (flags & MEM_MAPPING_IS_ROM) { - if (access & ACCESS_ROMCS) - ret = (flags & MEM_MAPPING_ROMCS); - else - ret = !(flags & MEM_MAPPING_ROMCS); - } else - ret = 1; - - ret = ret && !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); - } else - ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); - } else { - /* Still allow SMRAM if access is DISABLED but also has CACHE and/or SMRAM flags set. */ - if (access & ACCESS_CACHE) - ret = (flags & MEM_MAPPING_CACHE); - else if (access & ACCESS_SMRAM) - ret = (flags & MEM_MAPPING_SMRAM); - } - - return ret; -} - -void -mem_mapping_recalc(uint64_t base, uint64_t size) -{ - mem_mapping_t *map; - int n; - uint64_t c; - - if ((base >= 0xec000000) && (base <= 0xecffffff)) - pclog("mem_mapping_recalc(%016" PRIX64 ", %016" PRIX64 ")\n", base, size); - - if (!size || (base_mapping == NULL)) - return; - - map = base_mapping; - - /* Clear out old mappings. */ - for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { - _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - write_mapping_bus[c >> MEM_GRANULARITY_BITS] = NULL; - read_mapping_bus[c >> MEM_GRANULARITY_BITS] = NULL; - } - - /* Walk mapping list. */ - while (map != NULL) { - /* In range? */ - if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { - uint64_t start = (map->base < base) ? map->base : base; - uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? ((uint64_t) map->base + (uint64_t) map->size) : (base + size); - if (start < map->base) - start = map->base; - - for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { - /* CPU */ - n = !!in_smm; - if ((c >= 0xec000000) && (c <= 0xecffffff)) - pclog("mem_mapping_recalc(): map = %08X (%02X) (%02X, %02X, %02X)\n", map, map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x); - if (map->exec && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) - _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) - write_mapping[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) - read_mapping[c >> MEM_GRANULARITY_BITS] = map; - - /* Bus */ - n |= STATE_BUS; - if ((map->write_b || map->write_w || map->write_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) - write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) - read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; - } - } - map = map->next; - } - - flushmmucache_cr3(); - -#ifdef ENABLE_MEM_LOG - pclog("\nMemory map:\n"); - mem_mapping_t *write = (mem_mapping_t *) -1, *read = (mem_mapping_t *) -1, *write_bus = (mem_mapping_t *) -1, *read_bus = (mem_mapping_t *) -1; - for (c = 0; c < (sizeof(write_mapping) / sizeof(write_mapping[0])); c++) { - if ((write_mapping[c] == write) && (read_mapping[c] == read) && (write_mapping_bus[c] == write_bus) && (read_mapping_bus[c] == read_bus)) - continue; - write = write_mapping[c]; - read = read_mapping[c]; - write_bus = write_mapping_bus[c]; - read_bus = read_mapping_bus[c]; - - pclog("%08X | ", c << MEM_GRANULARITY_BITS); - if (read) { - pclog("R%c%c%c %08X+% 8X", - read->read_b ? 'b' : ' ', read->read_w ? 'w' : ' ', read->read_l ? 'l' : ' ', - read->base, read->size); - } else { - pclog(" "); - } - if (write) { - pclog(" | W%c%c%c %08X+% 8X", - write->write_b ? 'b' : ' ', write->write_w ? 'w' : ' ', write->write_l ? 'l' : ' ', - write->base, write->size); - } else { - pclog(" | "); - } - pclog(" | %c\n", _mem_exec[c] ? 'X' : ' '); - - if ((write != write_bus) || (read != read_bus)) { - pclog(" ^ bus | "); - if (read_bus) { - pclog("R%c%c%c %08X+% 8X", - read_bus->read_b ? 'b' : ' ', read_bus->read_w ? 'w' : ' ', read_bus->read_l ? 'l' : ' ', - read_bus->base, read_bus->size); - } else { - pclog(" "); - } - if (write_bus) { - pclog(" | W%c%c%c %08X+% 8X", - write_bus->write_b ? 'b' : ' ', write_bus->write_w ? 'w' : ' ', write_bus->write_l ? 'l' : ' ', - write_bus->base, write_bus->size); - } else { - pclog(" | "); - } - pclog(" |\n"); - } - } - pclog("\n"); -#endif -} - -void -mem_mapping_set(mem_mapping_t *map, - uint32_t base, - uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), - uint8_t *exec, - uint32_t fl, - void *p) -{ - if (size != 0x00000000) - map->enable = 1; - else - map->enable = 0; - map->base = base; - map->size = size; - map->mask = (map->size ? 0xffffffff : 0x00000000); - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - map->exec = exec; - map->flags = fl; - map->p = p; - map->next = NULL; - mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next); - - /* If the mapping is disabled, there is no need to recalc anything. */ - if (size != 0x00000000) - mem_mapping_recalc(map->base, map->size); -} - -void -mem_mapping_add(mem_mapping_t *map, - uint32_t base, - uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), - uint8_t *exec, - uint32_t fl, - void *p) -{ - /* Do a sanity check */ - if ((base_mapping == NULL) && (last_mapping != NULL)) { - fatal("mem_mapping_add(): NULL base mapping with non-NULL last mapping\n"); - return; - } else if ((base_mapping != NULL) && (last_mapping == NULL)) { - fatal("mem_mapping_add(): Non-NULL base mapping with NULL last mapping\n"); - return; - } else if ((base_mapping != NULL) && (base_mapping->prev != NULL)) { - fatal("mem_mapping_add(): Base mapping with a preceding mapping\n"); - return; - } else if ((last_mapping != NULL) && (last_mapping->next != NULL)) { - fatal("mem_mapping_add(): Last mapping with a following mapping\n"); - return; - } - - /* Add mapping to the beginning of the list if necessary.*/ - if (base_mapping == NULL) - base_mapping = map; - - /* Add mapping to the end of the list.*/ - if (last_mapping == NULL) - map->prev = NULL; - else { - map->prev = last_mapping; - last_mapping->next = map; - } - last_mapping = map; - - mem_mapping_set(map, base, size, read_b, read_w, read_l, - write_b, write_w, write_l, exec, fl, p); -} - -void -mem_mapping_do_recalc(mem_mapping_t *map) -{ - mem_mapping_recalc(map->base, map->size); -} - -void -mem_mapping_set_handler(mem_mapping_t *map, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)) -{ - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - - mem_mapping_recalc(map->base, map->size); -} - -void -mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) -{ - if ((base >= 0xec000000) && (base <= 0xecffffff)) - pclog("[0] mem_mapping_set_addr(%08X, %08X)\n", base, size); - - /* Remove old mapping. */ - map->enable = 0; - mem_mapping_recalc(map->base, map->size); - - if ((base >= 0xec000000) && (base <= 0xecffffff)) - pclog("[1] mem_mapping_set_addr(%08X, %08X)\n", base, size); - - /* Set new mapping. */ - map->enable = 1; - map->base = base; - map->size = size; - - if ((base >= 0xec000000) && (base <= 0xecffffff)) - pclog("[2] mem_mapping_set_addr(%08X, %08X)\n", base, size); - - mem_mapping_recalc((uint64_t) map->base, (uint64_t) map->size); -} - -void -mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) -{ - map->exec = exec; - - mem_mapping_recalc((uint64_t) map->base, (uint64_t) map->size); -} - -void -mem_mapping_set_mask(mem_mapping_t *map, uint32_t mask) -{ - map->mask = mask; - - mem_mapping_recalc((uint64_t) map->base, (uint64_t) map->size); -} - -void -mem_mapping_set_p(mem_mapping_t *map, void *p) -{ - map->p = p; -} - -void -mem_mapping_disable(mem_mapping_t *map) -{ - map->enable = 0; - - mem_mapping_recalc((uint64_t) map->base, (uint64_t) map->size); -} - -void -mem_mapping_enable(mem_mapping_t *map) -{ - map->enable = 1; - - mem_mapping_recalc((uint64_t) map->base, (uint64_t) map->size); -} - -void -mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t access) -{ - uint32_t c; - uint16_t mask, smstate = 0x0000; - const uint16_t smstates[4] = { 0x0000, (MEM_READ_SMRAM | MEM_WRITE_SMRAM), - MEM_READ_SMRAM_EX, (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX) }; - - int i; - - if (mode) - mask = 0x2d6b; - else - mask = 0x1084; - - if (mode) { - if (mode == 1) - access = !!access; - - if (mode == 3) { - if (access & ACCESS_SMRAM_X) - smstate |= MEM_EXEC_SMRAM; - if (access & ACCESS_SMRAM_R) - smstate |= MEM_READ_SMRAM_2; - if (access & ACCESS_SMRAM_W) - smstate |= MEM_WRITE_SMRAM; - } else - smstate = smstates[access & 0x07]; - } else - smstate = access & 0x6f7b; - - for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { - for (i = 0; i < 4; i++) { - if (bitmap & (1 << i)) { - _mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] & mask) | smstate; - } - } - -#ifdef ENABLE_MEM_LOG - if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) { - mem_log("Set mem state for block at %08X to %04X with bitmap %02X\n", - c + base, smstate, bitmap); - } -#endif - } - - mem_mapping_recalc(base, size); -} - -void -mem_a20_init(void) -{ - if (is286) { - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - rammask = cpu_16bitbus ? 0xffffff : 0xffffffff; - if (is6117) - rammask |= 0x03000000; - flushmmucache(); - // mem_a20_state = mem_a20_key | mem_a20_alt; - } else { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - } -} - -/* Close all the memory mappings. */ -void -mem_close(void) -{ - mem_mapping_t *map = base_mapping, *next; - - while (map != NULL) { - next = map->next; - map->prev = map->next = NULL; - map = next; - } - - base_mapping = last_mapping = 0; -} - -static void -mem_add_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size) -{ - mem_mapping_add(mapping, base, size, - mem_read_ram, mem_read_ramw, mem_read_raml, - mem_write_ram, mem_write_ramw, mem_write_raml, - ram + base, MEM_MAPPING_INTERNAL, NULL); -} - -static void -mem_init_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size) -{ - mem_set_mem_state_both(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_add_ram_mapping(mapping, base, size); -} - -/* Reset the memory state. */ -void -mem_reset(void) -{ - uint32_t c; - size_t m; - - memset(page_ff, 0xff, sizeof(page_ff)); - -#ifdef USE_NEW_DYNAREC - if (byte_dirty_mask) { - free(byte_dirty_mask); - byte_dirty_mask = NULL; - } - - if (byte_code_present_mask) { - free(byte_code_present_mask); - byte_code_present_mask = NULL; - } -#endif - - /* Free the old pages array, if necessary. */ - if (pages) { - free(pages); - pages = NULL; - } - - if (ram != NULL) { - plat_munmap(ram, ram_size); - ram = NULL; - ram_size = 0; - } -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (ram2 != NULL) { - plat_munmap(ram2, ram2_size); - ram2 = NULL; - ram2_size = 0; - } - - if (mem_size > 2097152) - mem_size = 2097152; -#endif - - m = 1024UL * (size_t) mem_size; - -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - ram_size = 1 << 30; - ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block of the first 1 GB */ - if (ram == NULL) { - fatal("Failed to allocate primary RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, ram_size); - ram2_size = m - (1 << 30); - ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */ - if (ram2 == NULL) { - if (config_changed == 2) - fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); - else - fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram2, 0x00, ram2_size); - } else -#endif - { - ram_size = m; - ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */ - if (ram == NULL) { - fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, ram_size); - if (mem_size > 1048576) - ram2 = &(ram[1 << 30]); - } - - /* - * Allocate the page table based on how much RAM we have. - * We re-allocate the table on each (hard) reset, as the - * memory amount could have changed. - */ - if (is286) { - if (cpu_16bitbus) { - /* 80286/386SX; maximum address space is 16MB. */ - m = 4096; - /* ALi M6117; maximum address space is 64MB. */ - if (is6117) - m <<= 2; - } else { - /* 80386DX+; maximum address space is 4GB. */ - m = 1048576; - } - } else { - /* 8088/86; maximum address space is 1MB. */ - m = 256; - } - - addr_space_size = m; - - /* - * Allocate and initialize the (new) page table. - */ - pages_sz = m; - pages = (page_t *) malloc(m * sizeof(page_t)); - - memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); - memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t)); - - memset(pages, 0x00, pages_sz * sizeof(page_t)); - -#ifdef USE_NEW_DYNAREC - byte_dirty_mask = malloc((mem_size * 1024) / 8); - memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); - - byte_code_present_mask = malloc((mem_size * 1024) / 8); - memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); -#endif - - for (c = 0; c < pages_sz; c++) { - if ((c << 12) >= (mem_size << 10)) - pages[c].mem = page_ff; - else { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - if ((c << 12) < (1 << 30)) - pages[c].mem = &ram[c << 12]; - else - pages[c].mem = &ram2[(c << 12) - (1 << 30)]; - } else - pages[c].mem = &ram[c << 12]; -#else - pages[c].mem = &ram[c << 12]; -#endif - } - if (c < m) { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } -#ifdef USE_NEW_DYNAREC - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; -#endif - } - - memset(_mem_exec, 0x00, sizeof(_mem_exec)); - memset(write_mapping, 0x00, sizeof(write_mapping)); - memset(read_mapping, 0x00, sizeof(read_mapping)); - memset(write_mapping_bus, 0x00, sizeof(write_mapping_bus)); - memset(read_mapping_bus, 0x00, sizeof(read_mapping_bus)); - - base_mapping = last_mapping = NULL; - - /* Set the entire memory space as external. */ - memset(_mem_state, 0x00, sizeof(_mem_state)); - - /* Set the low RAM space as internal. */ - mem_init_ram_mapping(&ram_low_mapping, 0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024); - - if (mem_size > 1024) { - if (cpu_16bitbus && !is6117 && mem_size > 16256) - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (16256 - 1024) * 1024); - else if (cpu_16bitbus && is6117 && mem_size > 65408) - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (65408 - 1024) * 1024); - else { - if (mem_size > 1048576) { - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (1048576 - 1024) * 1024); - - mem_set_mem_state_both((1 << 30), (mem_size - 1048576) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_2gb_mapping, (1 << 30), - ((mem_size - 1048576) * 1024), - mem_read_ram_2gb, mem_read_ram_2gbw, mem_read_ram_2gbl, - mem_write_ram, mem_write_ramw, mem_write_raml, - ram2, MEM_MAPPING_INTERNAL, NULL); - } else - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); - } - } - - if (mem_size > 768) { - mem_add_ram_mapping(&ram_mid_mapping, 0xa0000, 0x60000); - - mem_add_ram_mapping(&ram_mid_mapping2, 0xa0000, 0x60000); - mem_mapping_disable(&ram_mid_mapping2); - } - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, - mem_read_remapped, mem_read_remappedw, mem_read_remappedl, - mem_write_remapped, mem_write_remappedw, mem_write_remappedl, - ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - /* Mapping for SiS 471 relocation which relocates A0000-BFFFF, D0000-EFFFF, which is non-contiguous. */ - mem_mapping_add(&ram_remapped_mapping2, mem_size * 1024, 256 * 1024, - mem_read_remapped2, mem_read_remappedw2, mem_read_remappedl2, - mem_write_remapped2, mem_write_remappedw2, mem_write_remappedl2, - ram + 0xd0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping2); - - mem_a20_init(); - -#ifdef USE_NEW_DYNAREC - purgable_page_list_head = 0; - purgeable_page_count = 0; -#endif -} - -void -mem_init(void) -{ - /* Perform a one-time init. */ - ram = rom = NULL; - ram2 = NULL; - pages = NULL; - - /* Allocate the lookup tables. */ - page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *)); - page_lookupp = (uint8_t *) malloc((1 << 20) * sizeof(uint8_t)); - readlookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - readlookupp = malloc((1 << 20) * sizeof(uint8_t)); - writelookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - writelookupp = malloc((1 << 20) * sizeof(uint8_t)); -} - -void -mem_remap_top(int kb) -{ - uint32_t c; - uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int offset, size = mem_size - 640; - int set = 1; - static int old_kb = 0; - int sis_mode = 0; - uint32_t start_addr = 0, addr = 0; - - mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); - if (mem_size <= 640) - return; - - /* SiS 471 special mode. */ - if (kb == -256) { - kb = 256; - sis_mode = 1; - } - - /* Do not remap if we're have more than (16 MB - RAM) memory. */ - if ((kb != 0) && (mem_size >= (16384 - kb))) - return; - - if (kb == 0) { - kb = old_kb; - set = 0; - } else - old_kb = kb; - - if (size > kb) - size = kb; - - remap_start_addr = start << 10; - remap_start_addr2 = (start << 10) + 0x00020000; - - for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - offset = c - ((start * 1024) >> 12); - /* Use A0000-BFFFF, D0000-EFFFF instead of C0000-DFFFF, E0000-FFFFF. */ - addr = 0xa0000 + (offset << 12); - if (sis_mode) { - /* A0000-DFFFF -> A0000-BFFFF, D0000-EFFFF */ - if (addr >= 0x000c0000) - addr += 0x00010000; - } - if (start_addr == 0) - start_addr = addr; - pages[c].mem = set ? &ram[addr] : page_ff; - pages[c].write_b = set ? mem_write_ramb_page : NULL; - pages[c].write_w = set ? mem_write_ramw_page : NULL; - pages[c].write_l = set ? mem_write_raml_page : NULL; -#ifdef USE_NEW_DYNAREC - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[(addr >> 12) * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[(addr >> 12) * 64]; -#endif - } - - mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - - for (c = 0xa0; c < 0xf0; c++) { - if ((c >= 0xc0) && (c <= 0xcf)) - continue; - - if (sis_mode || ((c << 12) >= (mem_size << 10))) - pages[c].mem = page_ff; - else { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - if ((c << 12) < (1 << 30)) - pages[c].mem = &ram[c << 12]; - else - pages[c].mem = &ram2[(c << 12) - (1 << 30)]; - } else - pages[c].mem = &ram[c << 12]; -#else - pages[c].mem = &ram[c << 12]; -#endif - } - if (!sis_mode && (c < addr_space_size)) { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } else { - pages[c].write_b = NULL; - pages[c].write_w = NULL; - pages[c].write_l = NULL; - } -#ifdef USE_NEW_DYNAREC - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; -#endif - } - - if (set) { - if (sis_mode) { - mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, 0x00020000); - mem_mapping_set_exec(&ram_remapped_mapping, ram + 0x000a0000); - mem_mapping_set_addr(&ram_remapped_mapping2, (start * 1024) + 0x00020000, 0x00020000); - mem_mapping_set_exec(&ram_remapped_mapping2, ram + 0x000d0000); - - mem_mapping_set_addr(&ram_mid_mapping, 0x000c0000, 0x00010000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000c0000); - mem_mapping_set_addr(&ram_mid_mapping2, 0x000f0000, 0x00010000); - mem_mapping_set_exec(&ram_mid_mapping2, ram + 0x000f0000); - } else { - mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); - mem_mapping_set_exec(&ram_remapped_mapping, ram + start_addr); - mem_mapping_disable(&ram_remapped_mapping2); - - mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); - mem_mapping_disable(&ram_mid_mapping2); - } - } else { - mem_mapping_disable(&ram_remapped_mapping); - mem_mapping_disable(&ram_remapped_mapping2); - - mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); - mem_mapping_disable(&ram_mid_mapping2); - } - - flushmmucache(); -} - -void -mem_reset_page_blocks(void) -{ - uint32_t c; - - if (pages == NULL) - return; - - for (c = 0; c < pages_sz; c++) { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; -#ifdef USE_NEW_DYNAREC - pages[c].block = BLOCK_INVALID; - pages[c].block_2 = BLOCK_INVALID; - pages[c].head = BLOCK_INVALID; -#else - pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; - pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; - pages[c].head = NULL; -#endif - } -} - -void -mem_a20_recalc(void) -{ - int state; - - if (!is286) { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - - return; - } - - state = mem_a20_key | mem_a20_alt; - if (state && !mem_a20_state) { - rammask = (cpu_16bitbus) ? 0xffffff : 0xffffffff; - if (is6117) - rammask |= 0x03000000; - flushmmucache(); - } else if (!state && mem_a20_state) { - rammask = (cpu_16bitbus) ? 0xefffff : 0xffefffff; - if (is6117) - rammask |= 0x03000000; - flushmmucache(); - } - - mem_a20_state = state; -} diff --git a/src/mouse.patch b/src/mouse.patch deleted file mode 100644 index 4d9d67d2a..000000000 --- a/src/mouse.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff --git a/src/86box.c b/src/86box.c -index a14f51c41..3c96d88a4 100644 ---- a/src/86box.c -+++ b/src/86box.c -@@ -1263,9 +1263,9 @@ pc_run(void) - startblit(); - cpu_exec(cpu_s->rspeed / 100); - #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ -- if (gdbstub_step == GDBSTUB_EXEC) -+ // if (gdbstub_step == GDBSTUB_EXEC) - #endif -- mouse_process(); -+ // mouse_process(); - joystick_process(); - endblit(); - -diff --git a/src/device/mouse.c b/src/device/mouse.c -index 7eb6a08a9..329397d43 100644 ---- a/src/device/mouse.c -+++ b/src/device/mouse.c -@@ -27,6 +27,8 @@ - #define HAVE_STDARG_H - #include <86box/86box.h> - #include <86box/device.h> -+#include <86box/timer.h> -+#include <86box/gdbstub.h> - #include <86box/mouse.h> - - typedef struct { -@@ -45,6 +47,8 @@ int mouse_x, - double mouse_x_abs, - mouse_y_abs; - -+pc_timer_t mouse_timer; /* mouse event timer */ -+ - static const device_t mouse_none_device = { - .name = "None", - .internal_name = "none", -@@ -141,6 +145,20 @@ mouse_close(void) - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; -+ -+ timer_stop(&mouse_timer); -+} -+ -+static void -+mouse_timer_poll(void *priv) -+{ -+ // timer_on_auto(&mouse_timer, 1388.0 + (8.0 / 9.0)); -+ timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0)); -+ -+#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ -+ if (gdbstub_step == GDBSTUB_EXEC) -+#endif -+ mouse_process(); - } - - void -@@ -165,6 +183,9 @@ mouse_reset(void) - - if (mouse_curr != NULL) - mouse_priv = device_add(mouse_curr); -+ -+ timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); -+ timer_on_auto(&mouse_timer, 10000.0); - } - - /* Callback from the hardware driver. */ diff --git a/src/pic - Cópia.c b/src/pic - Cópia.c deleted file mode 100644 index 70a8a7805..000000000 --- a/src/pic - Cópia.c +++ /dev/null @@ -1,838 +0,0 @@ -/* - * 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. - * - * Implementation of the Intel PIC chip emulation, partially - * ported from reenigne's XTCE. - * - * - * - * Authors: Andrew Jenner, - * Miran Grca, - * - * Copyright 2015-2020 Andrew Jenner. - * Copyright 2016-2020 Miran Grca. - */ -#include -#include -#include -#include -#include -#include - -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/machine.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/pic.h> -#include <86box/timer.h> -#include <86box/pit.h> -#include <86box/device.h> -#include <86box/apm.h> -#include <86box/nvr.h> -#include <86box/acpi.h> - -enum { - STATE_NONE = 0, - STATE_ICW2, - STATE_ICW3, - STATE_ICW4 -}; - -pic_t pic, pic2; - -static pc_timer_t pic_timer; - -static int shadow = 0, elcr_enabled = 0, - tmr_inited = 0, latched = 0, - pic_pci = 0, kbd_latch = 0, - mouse_latch = 0; - -static uint16_t smi_irq_mask = 0x0000, - smi_irq_status = 0x0000; - -static uint16_t latched_irqs = 0x0000; - -static void (*update_pending)(void); - -#ifdef ENABLE_PIC_LOG -int pic_do_log = ENABLE_PIC_LOG; - -static void -pic_log(const char *fmt, ...) -{ - va_list ap; - - if (pic_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define pic_log(fmt, ...) -#endif - -void -pic_reset_smi_irq_mask(void) -{ - smi_irq_mask = 0x0000; -} - -void -pic_set_smi_irq_mask(int irq, int set) -{ - if ((irq >= 0) && (irq <= 15)) { - if (set) - smi_irq_mask |= (1 << irq); - else - smi_irq_mask &= ~(1 << irq); - } -} - -uint16_t -pic_get_smi_irq_status(void) -{ - return smi_irq_status; -} - -void -pic_clear_smi_irq_status(int irq) -{ - if ((irq >= 0) && (irq <= 15)) - smi_irq_status &= ~(1 << irq); -} - -void -pic_elcr_write(uint16_t port, uint8_t val, void *priv) -{ - pic_t *dev = (pic_t *) priv; - - pic_log("ELCR%i: WRITE %02X\n", port & 1, val); - - if (port & 1) - val &= 0xde; - else - val &= 0xf8; - - dev->elcr = val; - - pic_log("ELCR %i: %c %c %c %c %c %c %c %c\n", - port & 1, - (val & 1) ? 'L' : 'E', - (val & 2) ? 'L' : 'E', - (val & 4) ? 'L' : 'E', - (val & 8) ? 'L' : 'E', - (val & 0x10) ? 'L' : 'E', - (val & 0x20) ? 'L' : 'E', - (val & 0x40) ? 'L' : 'E', - (val & 0x80) ? 'L' : 'E'); -} - -uint8_t -pic_elcr_read(uint16_t port, void *priv) -{ - pic_t *dev = (pic_t *) priv; - - pic_log("ELCR%i: READ %02X\n", port & 1, dev->elcr); - - return dev->elcr; -} - -int -pic_elcr_get_enabled(void) -{ - return elcr_enabled; -} - -void -pic_elcr_set_enabled(int enabled) -{ - elcr_enabled = enabled; -} - -void -pic_elcr_io_handler(int set) -{ - io_handler(set, 0x04d0, 0x0001, - pic_elcr_read, NULL, NULL, - pic_elcr_write, NULL, NULL, &pic); - io_handler(set, 0x04d1, 0x0001, - pic_elcr_read, NULL, NULL, - pic_elcr_write, NULL, NULL, &pic2); -} - -static uint8_t -pic_cascade_mode(pic_t *dev) -{ - return !(dev->icw1 & 2); -} - -static __inline uint8_t -pic_slave_on(pic_t *dev, int channel) -{ - pic_log("pic_slave_on(%i): %i, %02X, %02X\n", channel, pic_cascade_mode(dev), dev->icw4 & 0x0c, dev->icw3 & (1 << channel)); - - return pic_cascade_mode(dev) && (dev->is_master || ((dev->icw4 & 0x0c) == 0x0c)) && (dev->icw3 & (1 << channel)); -} - -static __inline int -find_best_interrupt(pic_t *dev) -{ - uint8_t b; - uint8_t intr; - int i, j; - int ret = -1; - - for (i = 0; i < 8; i++) { - j = (i + dev->priority) & 7; - b = 1 << j; - - if (dev->isr & b) - break; - else if ((dev->state == 0) && ((dev->irr & ~dev->imr) & b)) { - ret = j; - break; - } - } - - intr = dev->interrupt = (ret == -1) ? 0x17 : ret; - - if (dev->at && (ret != -1)) { - if (dev == &pic2) - intr += 8; - - if (cpu_fast_off_flags & (1u << intr)) - cpu_fast_off_advance(); - } - - return ret; -} - -static __inline void -pic_update_pending_xt(void) -{ - if (find_best_interrupt(&pic) != -1) { - latched++; - if (latched == 1) - timer_on_auto(&pic_timer, 0.35); - } else if (latched == 0) - pic.int_pending = 0; -} - -static __inline void -pic_update_pending_at(void) -{ - pic2.int_pending = (find_best_interrupt(&pic2) != -1); - - if (pic2.int_pending) - pic.irr |= (1 << pic2.icw3); - else - pic.irr &= ~(1 << pic2.icw3); - - pic.int_pending = (find_best_interrupt(&pic) != -1); -} - -static void -pic_callback(void *priv) -{ - pic_t *dev = (pic_t *) priv; - - dev->int_pending = 1; - - latched--; - if (latched > 0) - timer_on_auto(&pic_timer, 0.35); -} - -void -pic_reset(void) -{ - int is_at = IS_AT(machine); - is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088"); - - memset(&pic, 0, sizeof(pic_t)); - memset(&pic2, 0, sizeof(pic_t)); - - pic.is_master = 1; - pic.interrupt = pic2.interrupt = 0x17; - - if (is_at) - pic.slaves[2] = &pic2; - - if (tmr_inited) - timer_on_auto(&pic_timer, 0.0); - memset(&pic_timer, 0x00, sizeof(pc_timer_t)); - timer_add(&pic_timer, pic_callback, &pic, 0); - tmr_inited = 1; - - update_pending = is_at ? pic_update_pending_at : pic_update_pending_xt; - pic.at = pic2.at = is_at; - - smi_irq_mask = smi_irq_status = 0x0000; - - shadow = 0; - pic_pci = 0; -} - -void -pic_set_shadow(int sh) -{ - shadow = sh; -} - -int -pic_get_pci_flag(void) -{ - return pic_pci; -} - -void -pic_set_pci_flag(int pci) -{ - pic_pci = pci; -} - -static uint8_t -pic_level_triggered(pic_t *dev, int irq) -{ - if (elcr_enabled) - return !!(dev->elcr & (1 << irq)); - else - return !!(dev->icw1 & 8); -} - -int -picint_is_level(int irq) -{ - return pic_level_triggered(((irq > 7) ? &pic2 : &pic), irq & 7); -} - -static void -pic_acknowledge(pic_t *dev) -{ - int pic_int = dev->interrupt & 7; - int pic_int_num = 1 << pic_int; - - dev->isr |= pic_int_num; - if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num)) - dev->irr &= ~pic_int_num; -} - -/* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ - priority with ISR bit set, that is also not masked if the PIC is in special mask mode. */ -static uint8_t -pic_non_specific_find(pic_t *dev) -{ - int i, j; - uint8_t b, irq = 0xff; - - for (i = 0; i < 8; i++) { - j = (i + dev->priority) & 7; - b = (1 << j); - - if ((dev->isr & b) && (!dev->special_mask_mode || !(dev->imr & b))) { - irq = j; - break; - } - } - - return irq; -} - -/* Do the EOI and rotation, if either is requested, on the given IRQ. */ -static void -pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate) -{ - uint8_t b = (1 << irq); - - if (irq != 0xff) { - if (eoi) - dev->isr &= ~b; - if (rotate) - dev->priority = (irq + 1) & 7; - - update_pending(); - } -} - -/* Automatic non-specific EOI. */ -static __inline void -pic_auto_non_specific_eoi(pic_t *dev) -{ - uint8_t irq; - - if (dev->icw4 & 2) { - irq = pic_non_specific_find(dev); - - pic_action(dev, irq, 1, dev->auto_eoi_rotate); - } -} - -/* Do the PIC command specified by bits 7-5 of the value written to the OCW2 register. */ -static void -pic_command(pic_t *dev) -{ - uint8_t irq = 0xff; - - if (dev->ocw2 & 0x60) { /* SL and/or EOI set */ - if (dev->ocw2 & 0x40) /* SL set, specific priority level */ - irq = (dev->ocw2 & 0x07); - else /* SL clear, non-specific priority level (find highest with ISR set) */ - irq = pic_non_specific_find(dev); - - pic_action(dev, irq, dev->ocw2 & 0x20, dev->ocw2 & 0x80); - } else /* SL and EOI clear */ - dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80); -} - -uint8_t -pic_latch_read(uint16_t addr, void *priv) -{ - uint8_t ret = 0xff; - - pic_log("pic_latch_read(%i, %i): %02X%02X\n", kbd_latch, mouse_latch, pic2.lines & 0x10, pic.lines & 0x02); - - if (kbd_latch && (latched_irqs & 0x0002)) - picintc(0x0002); - - if (mouse_latch && (latched_irqs & 0x1000)) - picintc(0x1000); - - /* Return FF - we just lower IRQ 1 and IRQ 12. */ - return ret; -} - -uint8_t -pic_read(uint16_t addr, void *priv) -{ - pic_t *dev = (pic_t *) priv; - - if (shadow) { - /* VIA PIC shadow read */ - if (addr & 0x0001) - dev->data_bus = ((dev->icw2 & 0xf8) >> 3) << 0; - else { - dev->data_bus = ((dev->ocw3 & 0x20) >> 5) << 4; - dev->data_bus |= ((dev->ocw2 & 0x80) >> 7) << 3; - dev->data_bus |= ((dev->icw4 & 0x10) >> 4) << 2; - dev->data_bus |= ((dev->icw4 & 0x02) >> 1) << 1; - dev->data_bus |= ((dev->icw4 & 0x08) >> 3) << 0; - } - } else { - /* Standard 8259 PIC read */ -#ifndef UNDEFINED_READ - /* Put the IRR on to the data bus by default until the real PIC is probed. */ - dev->data_bus = dev->irr; -#endif - if (dev->ocw3 & 0x04) { - dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */ - if (dev->int_pending) { - dev->data_bus = 0x80 | (dev->interrupt & 7); - pic_acknowledge(dev); - dev->int_pending = 0; - update_pending(); - } else - dev->data_bus = 0x00; - dev->ocw3 &= ~0x04; - } else if (addr & 0x0001) - dev->data_bus = dev->imr; - else if (dev->ocw3 & 0x02) { - if (dev->ocw3 & 0x01) - dev->data_bus = dev->isr; -#ifdef UNDEFINED_READ - else - dev->data_bus = 0x00; -#endif - } - /* If A0 = 0, VIA shadow is disabled, and poll mode is disabled, - simply read whatever is currently on the data bus. */ - } - - pic_log("pic_read(%04X, %08X) = %02X\n", addr, priv, dev->data_bus); - - return dev->data_bus; -} - -static void -pic_write(uint16_t addr, uint8_t val, void *priv) -{ - pic_t *dev = (pic_t *) priv; - - pic_log("pic_write(%04X, %02X, %08X)\n", addr, val, priv); - - dev->data_bus = val; - - if (addr & 0x0001) { - switch (dev->state) { - case STATE_ICW2: - dev->icw2 = val; - if (pic_cascade_mode(dev)) - dev->state = STATE_ICW3; - else - dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE; - break; - case STATE_ICW3: - dev->icw3 = val; - dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE; - break; - case STATE_ICW4: - dev->icw4 = val; - dev->state = STATE_NONE; - break; - case STATE_NONE: - dev->imr = val; - update_pending(); - break; - } - } else { - if (val & 0x10) { - /* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */ - if (pic_pci && (val & 0xe0)) - return; - - dev->icw1 = val; - dev->icw2 = dev->icw3 = 0x00; - if (!(dev->icw1 & 1)) - dev->icw4 = 0x00; - dev->ocw2 = dev->ocw3 = 0x00; - dev->irr = dev->lines; - dev->imr = dev->isr = 0x00; - dev->ack_bytes = dev->priority = 0x00; - dev->auto_eoi_rotate = dev->special_mask_mode = 0x00; - dev->interrupt = 0x17; - dev->int_pending = 0x00; - dev->state = STATE_ICW2; - update_pending(); - } else if (val & 0x08) { - dev->ocw3 = val; - if (dev->ocw3 & 0x04) - dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */ - if (dev->ocw3 & 0x40) - dev->special_mask_mode = !!(dev->ocw3 & 0x20); - } else { - dev->ocw2 = val; - pic_command(dev); - } - } -} - -void -pic_set_pci(void) -{ - int i; - - for (i = 0x0024; i < 0x0040; i += 4) { - io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); - io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); - } - - for (i = 0x1120; i < 0x1140; i += 4) { - io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); - io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); - } -} - -void -pic_kbd_latch(int enable) -{ - pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis"); - - if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch)) - io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); - - kbd_latch = !!enable; - - if (!enable) - picintc(0x0002); -} - -void -pic_mouse_latch(int enable) -{ - pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis"); - - if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch)) - io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL); - - mouse_latch = !!enable; - - if (!enable) - picintc(0x1000); -} - -static void -pic_reset_hard(void) -{ - pic_reset(); - - /* Explicitly reset the latches. */ - kbd_latch = mouse_latch = 0; - - /* The situation is as follows: There is a giant mess when it comes to these latches on real hardware, - to the point that there's even boards with board-level latched that get used in place of the latches - on the chipset, therefore, I'm just doing this here for the sake of simplicity. */ - if (machine_has_bus(machine, MACHINE_BUS_PS2)) { - pic_kbd_latch(0x01); - pic_mouse_latch(0x01); - } else { - pic_kbd_latch(0x00); - pic_mouse_latch(0x00); - } -} - -void -pic_init(void) -{ - pic_reset_hard(); - - shadow = 0; - io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); -} - -void -pic_init_pcjr(void) -{ - pic_reset_hard(); - - shadow = 0; - io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); -} - -void -pic2_init(void) -{ - io_sethandler(0x00a0, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); - pic.slaves[2] = &pic2; -} - -void -picint_common(uint16_t num, int level, int set) -{ - int i, raise; - uint8_t b, slaves = 0; - - /* Make sure to ignore all slave IRQ's, and in case of AT+, - translate IRQ 2 to IRQ 9. */ - for (i = 0; i < 8; i++) { - b = (1 << i); - raise = num & b; - - if (pic.icw3 & b) { - slaves++; - - if (raise) { - num &= ~b; - if (pic.at && (i == 2)) - num |= (1 << 9); - } - } - } - - if (!slaves) - num &= 0x00ff; - - if (!num) { - pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower"); - return; - } - - if (num & 0x0100) - acpi_rtc_status = !!set; - - if (set) { - if (smi_irq_mask & num) { - smi_raise(); - smi_irq_status |= num; - } - - if (num & 0xff00) { - if (level) - pic2.lines |= (num >> 8); - - /* Latch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs |= 0x1000; - - pic2.irr |= (num >> 8); - } - - if (num & 0x00ff) { - if (level) - pic.lines |= (num & 0x00ff); - - /* Latch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs |= 0x0002; - - pic.irr |= (num & 0x00ff); - } - } else { - smi_irq_status &= ~num; - - if (num & 0xff00) { - pic2.lines &= ~(num >> 8); - - /* Unlatch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs &= 0xefff; - - pic2.irr &= ~(num >> 8); - } - - if (num & 0x00ff) { - pic.lines &= ~(num & 0x00ff); - - /* Unlatch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs &= 0xfffd; - - pic.irr &= ~(num & 0x00ff); - } - } - - if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20)) - update_pending(); -} - -void -picint(uint16_t num) -{ - picint_common(num, 0, 1); -} - -void -picintlevel(uint16_t num) -{ - picint_common(num, 1, 1); -} - -void -picintc(uint16_t num) -{ - picint_common(num, 0, 0); -} - -static uint8_t -pic_i86_mode(pic_t *dev) -{ - return !!(dev->icw4 & 1); -} - -static uint8_t -pic_irq_ack_read(pic_t *dev, int phase) -{ - uint8_t intr = dev->interrupt & 0x47; - uint8_t slave = intr & 0x40; - intr &= 0x07; - pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase); - - if (dev != NULL) { - if (phase == 0) { - dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not - override the one currently being processed. */ - pic_acknowledge(dev); - if (slave) - dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); - else - dev->data_bus = pic_i86_mode(dev) ? 0xff : 0xcd; - } else if (pic_i86_mode(dev)) { - dev->int_pending = 0; - if (slave) - dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); - else - dev->data_bus = intr + (dev->icw2 & 0xf8); - pic_auto_non_specific_eoi(dev); - } else if (phase == 1) { - if (slave) - dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); - else if (dev->icw1 & 0x04) - dev->data_bus = (intr << 2) + (dev->icw1 & 0xe0); - else - dev->data_bus = (intr << 3) + (dev->icw1 & 0xc0); - } else if (phase == 2) { - dev->int_pending = 0; - if (slave) - dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); - else - dev->data_bus = dev->icw2; - pic_auto_non_specific_eoi(dev); - } - } - - return dev->data_bus; -} - -uint8_t -pic_irq_ack(void) -{ - int ret; - - /* Needed for Xi8088. */ - if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) { - if (!pic.slaves[pic.interrupt]->int_pending) { - /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ - fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); - exit(-1); - return -1; - } - - pic.interrupt |= 0x40; /* Mark slave pending. */ - } - - ret = pic_irq_ack_read(&pic, pic.ack_bytes); - pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); - - if (pic.ack_bytes == 0) { - /* Needed for Xi8088. */ - if (pic.interrupt & 0x40) - pic2.interrupt = 0x17; - pic.interrupt = 0x17; - update_pending(); - } - - return ret; -} - -int -picinterrupt(void) -{ - int i, ret = -1; - - if (pic.int_pending) { - if (pic_slave_on(&pic, pic.interrupt)) { - if (!pic.slaves[pic.interrupt]->int_pending) { - /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ - fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); - exit(-1); - return -1; - } - - pic.interrupt |= 0x40; /* Mark slave pending. */ - } - - if ((pic.interrupt == 0) && (pit_devs[1].data != NULL)) - pit_devs[1].set_gate(pit_devs[1].data, 0, 0); - - /* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */ - for (i = 0; i < 2; i++) { - ret = pic_irq_ack_read(&pic, pic.ack_bytes); - pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); - - if (pic.ack_bytes == 0) { - if (pic.interrupt & 0x40) - pic2.interrupt = 0x17; - pic.interrupt = 0x17; - update_pending(); - } - } - } - - return ret; -}