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;
-}