This commit is contained in:
OBattler
2025-08-02 14:03:20 +02:00
225 changed files with 19564 additions and 5314 deletions

View File

@@ -38,6 +38,7 @@ add_library(dev OBJECT
isapnp.c
kbc_at.c
kbc_at_dev.c
kbc_xt.c
keyboard.c
keyboard_at.c
keyboard_xt.c

View File

@@ -1391,10 +1391,10 @@ static const device_config_t ems5150_config[] = {
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = 0x0000 },
{ .description = "Board 1", .value = 0x0208 },
{ .description = "Board 2", .value = 0x020a },
{ .description = "Board 3", .value = 0x020c },
{ .description = "Board 4", .value = 0x020e },
{ .description = "208H", .value = 0x0208 },
{ .description = "20AH", .value = 0x020a },
{ .description = "20CH", .value = 0x020c },
{ .description = "20EH", .value = 0x020e },
{ .description = "" }
},
.bios = { { 0 } }

View File

@@ -248,7 +248,7 @@ static const device_config_t isarom_config[] = {
},
{
.name = "bios_addr",
.description = "BIOS Address",
.description = "BIOS address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0x00000,
@@ -557,7 +557,7 @@ static const device_config_t isarom_quad_config[] = {
static const device_config_t lba_enhancer_config[] = {
{
.name = "bios_addr",
.description = "BIOS Address",
.description = "BIOS address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xc8000,

View File

@@ -823,7 +823,7 @@ static const device_config_t mm58167_config[] = {
},
{
.name = "bios_addr",
.description = "BIOS Address",
.description = "BIOS address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xcc000,

View File

@@ -2661,7 +2661,15 @@ kbc_at_init(const device_t *info)
dev->ports[1] = kbc_at_ports[1];
/* The actual keyboard. */
device_add(&keyboard_at_generic_device);
if (keyboard_type == KEYBOARD_TYPE_INTERNAL) {
if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS))
device_add(((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? &keyboard_ps55_device :
&keyboard_ax_device);
else
device_add_params(&keyboard_at_generic_device, (void *) (uintptr_t)
(((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? FLAG_PS2_KBD : 0x00));
} else
keyboard_add_device();
fast_reset = 0x00;
@@ -2670,9 +2678,9 @@ kbc_at_init(const device_t *info)
return dev;
}
const device_t keyboard_at_device = {
.name = "PC/AT Keyboard",
.internal_name = "keyboard_at",
const device_t kbc_at_device = {
.name = "PC/AT Keyboard Controller",
.internal_name = "kbc_at",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_GENERIC,
.init = kbc_at_init,
@@ -2684,9 +2692,9 @@ const device_t keyboard_at_device = {
.config = NULL
};
const device_t keyboard_at_siemens_device = {
.name = "PC/AT Keyboard",
.internal_name = "keyboard_at",
const device_t kbc_at_siemens_device = {
.name = "PC/AT Keyboard Controller",
.internal_name = "kbc_at",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_SIEMENS,
.init = kbc_at_init,
@@ -2698,9 +2706,9 @@ const device_t keyboard_at_siemens_device = {
.config = NULL
};
const device_t keyboard_at_ami_device = {
.name = "PC/AT Keyboard (AMI)",
.internal_name = "keyboard_at_ami",
const device_t kbc_at_ami_device = {
.name = "PC/AT Keyboard Controller (AMI)",
.internal_name = "kbc_at_ami",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_AMI,
.init = kbc_at_init,
@@ -2712,9 +2720,9 @@ const device_t keyboard_at_ami_device = {
.config = NULL
};
const device_t keyboard_at_tg_ami_device = {
.name = "PC/AT Keyboard (TriGem AMI)",
.internal_name = "keyboard_at_tg_ami",
const device_t kbc_at_tg_ami_device = {
.name = "PC/AT Keyboard Controller (TriGem AMI)",
.internal_name = "kbc_at_tg_ami",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_TRIGEM_AMI,
.init = kbc_at_init,
@@ -2726,9 +2734,9 @@ const device_t keyboard_at_tg_ami_device = {
.config = NULL
};
const device_t keyboard_at_toshiba_device = {
.name = "PC/AT Keyboard (Toshiba)",
.internal_name = "keyboard_at_toshiba",
const device_t kbc_at_toshiba_device = {
.name = "PC/AT Keyboard Controller (Toshiba)",
.internal_name = "kbc_at_toshiba",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_TOSHIBA,
.init = kbc_at_init,
@@ -2740,9 +2748,9 @@ const device_t keyboard_at_toshiba_device = {
.config = NULL
};
const device_t keyboard_at_olivetti_device = {
.name = "PC/AT Keyboard (Olivetti)",
.internal_name = "keyboard_at_olivetti",
const device_t kbc_at_olivetti_device = {
.name = "PC/AT Keyboard Controller (Olivetti)",
.internal_name = "kbc_at_olivetti",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_OLIVETTI,
.init = kbc_at_init,
@@ -2754,9 +2762,9 @@ const device_t keyboard_at_olivetti_device = {
.config = NULL
};
const device_t keyboard_at_ncr_device = {
.name = "PC/AT Keyboard (NCR)",
.internal_name = "keyboard_at_ncr",
const device_t kbc_at_ncr_device = {
.name = "PC/AT Keyboard Controller (NCR)",
.internal_name = "kbc_at_ncr",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_NCR,
.init = kbc_at_init,
@@ -2768,9 +2776,9 @@ const device_t keyboard_at_ncr_device = {
.config = NULL
};
const device_t keyboard_at_compaq_device = {
.name = "PC/AT Keyboard (Compaq)",
.internal_name = "keyboard_at_compaq",
const device_t kbc_at_compaq_device = {
.name = "PC/AT Keyboard Controller (Compaq)",
.internal_name = "kbc_at_compaq",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_COMPAQ,
.init = kbc_at_init,
@@ -2782,9 +2790,9 @@ const device_t keyboard_at_compaq_device = {
.config = NULL
};
const device_t keyboard_at_phoenix_device = {
.name = "PC/AT Keyboard (Phoenix)",
.internal_name = "keyboard_at_phoenix",
const device_t kbc_at_phoenix_device = {
.name = "PC/AT Keyboard Controller (Phoenix)",
.internal_name = "kbc_at_phoenix",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_PHOENIX,
.init = kbc_at_init,
@@ -2796,9 +2804,9 @@ const device_t keyboard_at_phoenix_device = {
.config = NULL
};
const device_t keyboard_ps2_device = {
.name = "PS/2 Keyboard",
.internal_name = "keyboard_ps2",
const device_t kbc_ps2_device = {
.name = "PS/2 Keyboard Controller",
.internal_name = "kbc_ps2",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
.init = kbc_at_init,
@@ -2810,9 +2818,9 @@ const device_t keyboard_ps2_device = {
.config = NULL
};
const device_t keyboard_ps2_ps1_device = {
.name = "PS/2 Keyboard (IBM PS/1)",
.internal_name = "keyboard_ps2_ps1",
const device_t kbc_ps2_ps1_device = {
.name = "PS/2 Keyboard Controller (IBM PS/1)",
.internal_name = "kbc_ps2_ps1",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1,
.init = kbc_at_init,
@@ -2824,9 +2832,9 @@ const device_t keyboard_ps2_ps1_device = {
.config = NULL
};
const device_t keyboard_ps2_ps1_pci_device = {
.name = "PS/2 Keyboard (IBM PS/1)",
.internal_name = "keyboard_ps2_ps1_pci",
const device_t kbc_ps2_ps1_pci_device = {
.name = "PS/2 Keyboard Controller (IBM PS/1)",
.internal_name = "kbc_ps2_ps1_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1,
.init = kbc_at_init,
@@ -2838,9 +2846,9 @@ const device_t keyboard_ps2_ps1_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_xi8088_device = {
.name = "PS/2 Keyboard (Xi8088)",
.internal_name = "keyboard_ps2_xi8088",
const device_t kbc_ps2_xi8088_device = {
.name = "PS/2 Keyboard Controller (Xi8088)",
.internal_name = "kbc_ps2_xi8088",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
.init = kbc_at_init,
@@ -2852,9 +2860,9 @@ const device_t keyboard_ps2_xi8088_device = {
.config = NULL
};
const device_t keyboard_ps2_ami_device = {
.name = "PS/2 Keyboard (AMI)",
.internal_name = "keyboard_ps2_ami",
const device_t kbc_ps2_ami_device = {
.name = "PS/2 Keyboard Controller (AMI)",
.internal_name = "kbc_ps2_ami",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_AMI,
.init = kbc_at_init,
@@ -2866,9 +2874,9 @@ const device_t keyboard_ps2_ami_device = {
.config = NULL
};
const device_t keyboard_ps2_compaq_device = {
.name = "PS/2 Keyboard (Compaq)",
.internal_name = "keyboard_at_compaq",
const device_t kbc_ps2_compaq_device = {
.name = "PS/2 Keyboard Controller (Compaq)",
.internal_name = "kbc_at_compaq",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_COMPAQ,
.init = kbc_at_init,
@@ -2880,9 +2888,9 @@ const device_t keyboard_ps2_compaq_device = {
.config = NULL
};
const device_t keyboard_ps2_holtek_device = {
.name = "PS/2 Keyboard (Holtek)",
.internal_name = "keyboard_ps2_holtek",
const device_t kbc_ps2_holtek_device = {
.name = "PS/2 Keyboard Controller (Holtek)",
.internal_name = "kbc_ps2_holtek",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_FLAG_IS_ASIC,
.init = kbc_at_init,
@@ -2894,9 +2902,9 @@ const device_t keyboard_ps2_holtek_device = {
.config = NULL
};
const device_t keyboard_ps2_phoenix_device = {
.name = "PS/2 Keyboard (Phoenix)",
.internal_name = "keyboard_ps2_phoenix",
const device_t kbc_ps2_phoenix_device = {
.name = "PS/2 Keyboard Controller (Phoenix)",
.internal_name = "kbc_ps2_phoenix",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX,
.init = kbc_at_init,
@@ -2908,9 +2916,9 @@ const device_t keyboard_ps2_phoenix_device = {
.config = NULL
};
const device_t keyboard_ps2_tg_ami_device = {
.name = "PS/2 Keyboard (TriGem AMI)",
.internal_name = "keyboard_ps2_tg_ami",
const device_t kbc_ps2_tg_ami_device = {
.name = "PS/2 Keyboard Controller (TriGem AMI)",
.internal_name = "kbc_ps2_tg_ami",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI,
.init = kbc_at_init,
@@ -2922,9 +2930,9 @@ const device_t keyboard_ps2_tg_ami_device = {
.config = NULL
};
const device_t keyboard_ps2_mca_1_device = {
.name = "PS/2 Keyboard (IBM PS/2 MCA Type 1)",
.internal_name = "keyboard_ps2_mca_1",
const device_t kbc_ps2_mca_1_device = {
.name = "PS/2 Keyboard Controller (IBM PS/2 MCA Type 1)",
.internal_name = "kbc_ps2_mca_1",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_IBM,
.init = kbc_at_init,
@@ -2936,9 +2944,9 @@ const device_t keyboard_ps2_mca_1_device = {
.config = NULL
};
const device_t keyboard_ps2_mca_2_device = {
.name = "PS/2 Keyboard (IBM PS/2 MCA Type 2)",
.internal_name = "keyboard_ps2_mca_2",
const device_t kbc_ps2_mca_2_device = {
.name = "PS/2 Keyboard Controller (IBM PS/2 MCA Type 2)",
.internal_name = "kbc_ps2_mca_2",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_2 | KBC_VEN_IBM,
.init = kbc_at_init,
@@ -2950,9 +2958,9 @@ const device_t keyboard_ps2_mca_2_device = {
.config = NULL
};
const device_t keyboard_ps2_quadtel_device = {
.name = "PS/2 Keyboard (Quadtel/MegaPC)",
.internal_name = "keyboard_ps2_quadtel",
const device_t kbc_ps2_quadtel_device = {
.name = "PS/2 Keyboard Controller (Quadtel/MegaPC)",
.internal_name = "kbc_ps2_quadtel",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL,
.init = kbc_at_init,
@@ -2964,9 +2972,9 @@ const device_t keyboard_ps2_quadtel_device = {
.config = NULL
};
const device_t keyboard_ps2_pci_device = {
.name = "PS/2 Keyboard",
.internal_name = "keyboard_ps2_pci",
const device_t kbc_ps2_pci_device = {
.name = "PS/2 Keyboard Controller (PCI)",
.internal_name = "kbc_ps2_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
.init = kbc_at_init,
@@ -2978,9 +2986,9 @@ const device_t keyboard_ps2_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_ami_pci_device = {
.name = "PS/2 Keyboard (AMI)",
.internal_name = "keyboard_ps2_ami_pci",
const device_t kbc_ps2_ami_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (AMI)",
.internal_name = "kbc_ps2_ami_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_AMI,
.init = kbc_at_init,
@@ -2992,9 +3000,9 @@ const device_t keyboard_ps2_ami_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_ali_pci_device = {
.name = "PS/2 Keyboard (ALi M5123/M1543C)",
.internal_name = "keyboard_ps2_ali_pci",
const device_t kbc_ps2_ali_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (ALi M5123/M1543C)",
.internal_name = "kbc_ps2_ali_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_ALI,
.init = kbc_at_init,
@@ -3006,9 +3014,9 @@ const device_t keyboard_ps2_ali_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_intel_ami_pci_device = {
.name = "PS/2 Keyboard (AMI)",
.internal_name = "keyboard_ps2_intel_ami_pci",
const device_t kbc_ps2_intel_ami_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (AMI)",
.internal_name = "kbc_ps2_intel_ami_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_GREEN | KBC_VEN_AMI,
.init = kbc_at_init,
@@ -3020,9 +3028,9 @@ const device_t keyboard_ps2_intel_ami_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_tg_ami_pci_device = {
.name = "PS/2 Keyboard (TriGem AMI)",
.internal_name = "keyboard_ps2_tg_ami_pci",
const device_t kbc_ps2_tg_ami_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (TriGem AMI)",
.internal_name = "kbc_ps2_tg_ami_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI,
.init = kbc_at_init,
@@ -3034,9 +3042,9 @@ const device_t keyboard_ps2_tg_ami_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_acer_pci_device = {
.name = "PS/2 Keyboard (Acer 90M002A)",
.internal_name = "keyboard_ps2_acer_pci",
const device_t kbc_ps2_acer_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (Acer 90M002A)",
.internal_name = "kbc_ps2_acer_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_ACER,
.init = kbc_at_init,
@@ -3048,9 +3056,9 @@ const device_t keyboard_ps2_acer_pci_device = {
.config = NULL
};
const device_t keyboard_ps2_phoenix_pci_device = {
.name = "PS/2 Keyboard (Phoenix)",
.internal_name = "keyboard_ps2_phoenix_pci",
const device_t kbc_ps2_phoenix_pci_device = {
.name = "PS/2 Keyboard Controller (PCI) (Phoenix)",
.internal_name = "kbc_ps2_phoenix_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX,
.init = kbc_at_init,

903
src/device/kbc_xt.c Normal file
View File

@@ -0,0 +1,903 @@
/*
* 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 XT-style keyboard.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* EngiNerd, <webmaster.crrc@yahoo.it>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van kempen.
* Copyright 2020 EngiNerd.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define HAVE_STDARG_H
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/fdd.h>
#include <86box/machine.h>
#include <86box/m_xt_t1000.h>
#include <86box/cassette.h>
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/ppi.h>
#include <86box/mem.h>
#include <86box/rom.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_LOCK 0x10
#define STAT_CD 0x08
#define STAT_SYSFLAG 0x04
#define STAT_IFULL 0x02
#define STAT_OFULL 0x01
/* Keyboard Types */
enum {
KBD_TYPE_PC81 = 0,
KBD_TYPE_PC82,
KBD_TYPE_XT82,
KBD_TYPE_XT86,
KBD_TYPE_COMPAQ,
KBD_TYPE_TANDY,
KBD_TYPE_TOSHIBA,
KBD_TYPE_VTECH,
KBD_TYPE_OLIVETTI,
KBD_TYPE_ZENITH,
KBD_TYPE_PRAVETZ,
KBD_TYPE_HYUNDAI,
KBD_TYPE_FE2010,
KBD_TYPE_XTCLONE
};
typedef struct xtkbd_t {
int want_irq;
int blocked;
int tandy;
uint8_t pa;
uint8_t pb;
uint8_t pd;
uint8_t cfg;
uint8_t clock;
uint8_t key_waiting;
uint8_t type;
uint8_t pravetz_flags;
uint8_t cpu_speed;
pc_timer_t send_delay_timer;
} xtkbd_t;
static uint8_t key_queue[16];
static int key_queue_start = 0;
static int key_queue_end = 0;
static int is_tandy = 0;
static int is_t1x00 = 0;
static int is_amstrad = 0;
#ifdef ENABLE_KEYBOARD_XT_LOG
int keyboard_xt_do_log = ENABLE_KEYBOARD_XT_LOG;
static void
kbd_log(const char *fmt, ...)
{
va_list ap;
if (keyboard_xt_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define kbd_log(fmt, ...)
#endif
static uint8_t
get_fdd_switch_settings(void)
{
uint8_t fdd_count = 0;
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fdd_get_flags(i))
fdd_count++;
}
if (!fdd_count)
return 0x00;
else
return ((fdd_count - 1) << 6) | 0x01;
}
static uint8_t
get_videomode_switch_settings(void)
{
if (video_is_mda())
return 0x30;
else if (video_is_cga())
return 0x20; /* 0x10 would be 40x25 */
else
return 0x00;
}
static void
kbd_poll(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
timer_advance_u64(&kbd->send_delay_timer, 1000 * TIMER_USEC);
if (!(kbd->pb & 0x40) && (kbd->type != KBD_TYPE_TANDY))
return;
if (kbd->want_irq) {
kbd->want_irq = 0;
kbd->pa = kbd->key_waiting;
kbd->blocked = 1;
picint(2);
#ifdef ENABLE_KEYBOARD_XT_LOG
kbd_log("XTkbd: kbd_poll(): keyboard_xt : take IRQ\n");
#endif
}
if ((key_queue_start != key_queue_end) && !kbd->blocked) {
kbd->key_waiting = key_queue[key_queue_start];
kbd_log("XTkbd: reading %02X from the key queue at %i\n",
kbd->key_waiting, key_queue_start);
key_queue_start = (key_queue_start + 1) & 0x0f;
kbd->want_irq = 1;
}
}
static void
kbd_adddata(uint16_t val)
{
/* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */
if (is_t1x00) {
if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */
t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */
switch (val) {
case 0x45: /* Num Lock => toggle numpad */
t1000_syskey(0x00, 0x00, 0x10);
break;
case 0x47: /* Home => internal display */
t1000_syskey(0x40, 0x00, 0x00);
break;
case 0x49: /* PgDn => turbo on */
t1000_syskey(0x80, 0x00, 0x00);
break;
case 0x4D: /* Right => toggle LCD font */
t1000_syskey(0x00, 0x00, 0x20);
break;
case 0x4F: /* End => external display */
t1000_syskey(0x00, 0x40, 0x00);
break;
case 0x51: /* PgDn => turbo off */
t1000_syskey(0x00, 0x80, 0x00);
break;
case 0x54: /* SysRQ => toggle window */
t1000_syskey(0x00, 0x00, 0x08);
break;
default:
break;
}
} else
t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */
}
key_queue[key_queue_end] = val;
kbd_log("XTkbd: %02X added to key queue at %i\n",
val, key_queue_end);
key_queue_end = (key_queue_end + 1) & 0x0f;
}
void
kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val))
{
uint8_t num_lock = 0;
uint8_t shift_states = 0;
if (!adddata)
return;
keyboard_get_states(NULL, &num_lock, NULL, NULL);
shift_states = keyboard_get_shift() & STATE_LSHIFT;
if (is_amstrad)
num_lock = !num_lock;
/* If NumLock is on, invert the left shift state so we can always check for
the the same way flag being set (and with NumLock on that then means it
is actually *NOT* set). */
if (num_lock)
shift_states ^= STATE_LSHIFT;
switch (val) {
case FAKE_LSHIFT_ON:
/* If NumLock is on, fake shifts are sent when shift is *NOT* presed,
if NumLock is off, fake shifts are sent when shift is pressed. */
if (shift_states) {
/* Send fake shift. */
adddata(num_lock ? 0x2a : 0xaa);
}
break;
case FAKE_LSHIFT_OFF:
if (shift_states) {
/* Send fake shift. */
adddata(num_lock ? 0xaa : 0x2a);
}
break;
default:
adddata(val);
break;
}
}
static void
kbd_adddata_ex(uint16_t val)
{
kbd_adddata_process(val, kbd_adddata);
}
static void
kbd_write(uint16_t port, uint8_t val, void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
uint8_t bit;
uint8_t set;
uint8_t new_clock;
switch (port) {
case 0x61: /* Keyboard Control Register (aka Port B) */
if (!(val & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) {
new_clock = !!(val & 0x40);
if (!kbd->clock && new_clock) {
key_queue_start = key_queue_end = 0;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd_adddata(0xaa);
}
}
kbd->pb = val;
if (!(kbd->pb & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI))
kbd->clock = !!(kbd->pb & 0x40);
ppi.pb = val;
timer_process();
if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) && (cassette != NULL))
pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0);
speaker_update();
speaker_gated = val & 1;
speaker_enable = val & 2;
if (speaker_enable)
was_speaker_enable = 1;
pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1);
if (val & 0x80) {
kbd->pa = 0;
kbd->blocked = 0;
picintc(2);
}
#ifdef ENABLE_KEYBOARD_XT_LOG
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
#endif
break;
case 0x62: /* Switch Register (aka Port C) */
#ifdef ENABLE_KEYBOARD_XT_LOG
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10));
#endif
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Switch register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->pd = (kbd->pd & 0x30) | (val & 0xcf);
}
break;
case 0x63:
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Configuration register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->cfg = val;
}
break;
case 0xc0 ... 0xcf: /* Pravetz Flags */
kbd_log("XTkbd: Port %02X out: %02X\n", port, val);
if (kbd->type == KBD_TYPE_PRAVETZ) {
bit = (port >> 1) & 0x07;
set = (port & 0x01) << bit;
kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set;
}
break;
case 0x1f0:
kbd_log("XTkbd: Port %04X out: %02X\n", port, val);
if (kbd->type == KBD_TYPE_VTECH) {
kbd->cpu_speed = val;
cpu_dynamic_switch(kbd->cpu_speed >> 7);
}
break;
default:
break;
}
}
static uint8_t
kbd_read(uint16_t port, void *priv)
{
const xtkbd_t *kbd = (xtkbd_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x60: /* Keyboard Data Register (aka Port A) */
if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) ||
(kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) ||
(kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))) {
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_HYUNDAI))
ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00);
else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_VTECH))
/* According to Ruud on the PCem forum, this is supposed to
return 0xFF on the XT. */
ret = 0xff;
else if (kbd->type == KBD_TYPE_ZENITH) {
/* Zenith Data Systems Z-151
* SW1 switch settings:
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bit 2-3: base memory size
* bit 1: fpu enable
* bit 0: fdc enable
*/
ret = get_fdd_switch_settings();
ret |= get_videomode_switch_settings();
/* Base memory size should always be 64k */
ret |= 0x0c;
if (hasfpu)
ret |= 0x02;
}
} else
ret = kbd->pa;
break;
case 0x61: /* Keyboard Control Register (aka Port B) */
ret = kbd->pb;
break;
case 0x62: /* Switch Register (aka Port C) */
if (kbd->type == KBD_TYPE_FE2010) {
if (kbd->pb & 0x04) /* PB2 */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
else
ret = kbd->pd >> 4;
} else if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) {
if (kbd->pb & 0x04) /* PB2 */
switch (mem_size + isa_mem_size) {
case 64:
case 48:
case 32:
case 16:
ret = 0x00;
break;
default:
ret = (((mem_size + isa_mem_size) - 64) / 32) & 0x0f;
break;
}
else
ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4;
} else if ((kbd->type == KBD_TYPE_OLIVETTI) ||
(kbd->type == KBD_TYPE_ZENITH)) {
/* Olivetti M19 or Zenith Data Systems Z-151 */
if (kbd->pb & 0x04) /* PB2 */
ret = kbd->pd & 0xbf;
else
ret = kbd->pd >> 4;
} else {
if (kbd->pb & 0x08) /* PB3 */
ret = kbd->pd >> 4;
else
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
ret |= (ppispeakon ? 0x20 : 0);
/* This is needed to avoid error 131 (cassette error).
This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) {
if (cassette == NULL)
ret |= (ppispeakon ? 0x10 : 0);
else
ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0);
}
if (kbd->type == KBD_TYPE_TANDY)
ret |= (tandy1k_eeprom_read() ? 0x10 : 0);
break;
case 0x63: /* Keyboard Configuration Register (aka Port D) */
if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))
ret = kbd->pd;
break;
case 0xc0: /* Pravetz Flags */
if (kbd->type == KBD_TYPE_PRAVETZ)
ret = kbd->pravetz_flags;
kbd_log("XTkbd: Port %02X in : %02X\n", port, ret);
break;
case 0x1f0:
if (kbd->type == KBD_TYPE_VTECH)
ret = kbd->cpu_speed;
kbd_log("XTkbd: Port %04X in : %02X\n", port, ret);
break;
default:
break;
}
return ret;
}
static void
kbd_reset(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd->pa = 0x00;
kbd->pb = 0x00;
kbd->pravetz_flags = 0x00;
keyboard_scan = 1;
key_queue_start = 0;
key_queue_end = 0;
}
void
keyboard_set_is_amstrad(int ams)
{
is_amstrad = ams;
}
static void *
kbd_init(const device_t *info)
{
xtkbd_t *kbd;
kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t));
io_sethandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
keyboard_send = kbd_adddata_ex;
kbd->type = info->local;
if (kbd->type == KBD_TYPE_VTECH)
kbd->cpu_speed = (!!cpu) << 2;
kbd_reset(kbd);
if (kbd->type == KBD_TYPE_PRAVETZ)
io_sethandler(0x00c0, 16,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
if (kbd->type == KBD_TYPE_VTECH)
io_sethandler(0x01f0, 1,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
key_queue_start = key_queue_end = 0;
video_reset(gfxcard[0]);
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) ||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) {
/* DIP switch readout: bit set = OFF, clear = ON. */
if (kbd->type == KBD_TYPE_OLIVETTI)
/* Olivetti M19
* Jumpers J1, J2 - monitor type.
* 01 - mono (high-res)
* 10 - color (low-res, disables 640x400x2 mode)
* 00 - autoswitching
*/
kbd->pd |= 0x00;
else
/* Switches 7, 8 - floppy drives. */
kbd->pd = get_fdd_switch_settings();
/* Switches 5, 6 - video card type */
kbd->pd |= get_videomode_switch_settings();
/* Switches 3, 4 - memory size. */
if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) {
switch (mem_size) {
case 256:
kbd->pd |= 0x00;
break;
case 512:
kbd->pd |= 0x04;
break;
case 576:
kbd->pd |= 0x08;
break;
case 640:
default:
kbd->pd |= 0x0c;
break;
}
} else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_VTECH)) {
switch (mem_size) {
case 64: /* 1x64k */
kbd->pd |= 0x00;
break;
case 128: /* 2x64k */
kbd->pd |= 0x04;
break;
case 192: /* 3x64k */
kbd->pd |= 0x08;
break;
case 256: /* 4x64k */
default:
kbd->pd |= 0x0c;
break;
}
} else if (kbd->type == KBD_TYPE_PC82) {
switch (mem_size) {
#ifdef PC82_192K_3BANK
case 192: /* 3x64k, not supported by stock BIOS due to bugs */
kbd->pd |= 0x08;
break;
#else
case 192: /* 2x64k + 2x32k */
#endif
case 64: /* 4x16k */
case 96: /* 2x32k + 2x16k */
case 128: /* 4x32k */
case 160: /* 2x64k + 2x16k */
case 224: /* 3x64k + 1x32k */
case 256: /* 4x64k */
default:
kbd->pd |= 0x0c;
break;
}
} else { /* really just the PC '81 */
switch (mem_size) {
case 16: /* 1x16k */
kbd->pd |= 0x00;
break;
case 32: /* 2x16k */
kbd->pd |= 0x04;
break;
case 48: /* 3x16k */
kbd->pd |= 0x08;
break;
case 64: /* 4x16k */
default:
kbd->pd |= 0x0c;
break;
}
}
/* Switch 2 - 8087 FPU. */
if (hasfpu)
kbd->pd |= 0x02;
} else if (kbd->type == KBD_TYPE_ZENITH) {
/* Zenith Data Systems Z-151
* SW2 switch settings:
* bit 7: monitor frequency
* bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd)
* bits 0-4: installed memory
*/
kbd->pd = 0x20;
switch (mem_size) {
case 128:
kbd->pd |= 0x02;
break;
case 192:
kbd->pd |= 0x04;
break;
case 256:
kbd->pd |= 0x06;
break;
case 320:
kbd->pd |= 0x08;
break;
case 384:
kbd->pd |= 0x0a;
break;
case 448:
kbd->pd |= 0x0c;
break;
case 512:
kbd->pd |= 0x0e;
break;
case 576:
kbd->pd |= 0x10;
break;
case 640:
default:
kbd->pd |= 0x12;
break;
}
}
timer_add(&kbd->send_delay_timer, kbd_poll, kbd, 1);
is_tandy = (kbd->type == KBD_TYPE_TANDY);
is_t1x00 = (kbd->type == KBD_TYPE_TOSHIBA);
if (keyboard_type == KEYBOARD_TYPE_INTERNAL)
keyboard_set_table(scancode_xt);
else
keyboard_add_device();
is_amstrad = 0;
return kbd;
}
static void
kbd_close(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
/* Stop the timer. */
timer_disable(&kbd->send_delay_timer);
/* Disable scanning. */
keyboard_scan = 0;
keyboard_send = NULL;
io_removehandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
free(kbd);
}
const device_t kbc_pc_device = {
.name = "IBM PC Keyboard Controller (1981)",
.internal_name = "kbc_pc",
.flags = 0,
.local = KBD_TYPE_PC81,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_pc82_device = {
.name = "IBM PC Keyboard Controller (1982)",
.internal_name = "kbc_pc82",
.flags = 0,
.local = KBD_TYPE_PC82,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_pravetz_device = {
.name = "Pravetz Keyboard Controller",
.internal_name = "kbc_pravetz",
.flags = 0,
.local = KBD_TYPE_PRAVETZ,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_device = {
.name = "XT (1982) Keyboard Controller",
.internal_name = "kbc_xt",
.flags = 0,
.local = KBD_TYPE_XT82,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt86_device = {
.name = "XT (1986) Keyboard Controller",
.internal_name = "kbc_xt86",
.flags = 0,
.local = KBD_TYPE_XT86,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_compaq_device = {
.name = "Compaq Portable Keyboard Controller",
.internal_name = "kbc_xt_compaq",
.flags = 0,
.local = KBD_TYPE_COMPAQ,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_tandy_device = {
.name = "Tandy 1000 Keyboard Controller",
.internal_name = "kbc_tandy",
.flags = 0,
.local = KBD_TYPE_TANDY,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_t1x00_device = {
.name = "Toshiba T1x00 Keyboard Controller",
.internal_name = "kbc_xt_t1x00",
.flags = 0,
.local = KBD_TYPE_TOSHIBA,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_lxt3_device = {
.name = "VTech Laser Turbo XT Keyboard Controller",
.internal_name = "kbc_xt_lxt",
.flags = 0,
.local = KBD_TYPE_VTECH,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_olivetti_device = {
.name = "Olivetti XT Keyboard Controller",
.internal_name = "kbc_xt_olivetti",
.flags = 0,
.local = KBD_TYPE_OLIVETTI,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_zenith_device = {
.name = "Zenith XT Keyboard Controller",
.internal_name = "kbc_xt_zenith",
.flags = 0,
.local = KBD_TYPE_ZENITH,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_hyundai_device = {
.name = "Hyundai XT Keyboard Controller",
.internal_name = "kbc_xt_hyundai",
.flags = 0,
.local = KBD_TYPE_HYUNDAI,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xt_fe2010_device = {
.name = "Faraday FE2010 XT Keyboard Controller",
.internal_name = "kbc_xt_fe2010",
.flags = 0,
.local = KBD_TYPE_FE2010,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t kbc_xtclone_device = {
.name = "XT (Clone) Keyboard Controller",
.internal_name = "kbc_xtclone",
.flags = 0,
.local = KBD_TYPE_XTCLONE,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -27,6 +27,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/plat.h>
@@ -36,6 +37,38 @@ uint16_t scancode_map[768] = { 0 };
int keyboard_scan;
typedef struct keyboard_t {
const device_t *device;
} keyboard_t;
int keyboard_type = 0;
static const device_t keyboard_internal_device = {
.name = "Internal",
.internal_name = "internal",
.flags = 0,
.local = KEYBOARD_TYPE_INTERNAL,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
static keyboard_t keyboard_devices[] = {
// clang-format off
{ &keyboard_internal_device },
{ &keyboard_pc_xt_device },
{ &keyboard_at_device },
{ &keyboard_ax_device },
{ &keyboard_ps2_device },
{ &keyboard_ps55_device },
{ NULL }
// clang-format on
};
#ifdef ENABLE_KBC_AT_LOG
int kbc_at_do_log = ENABLE_KBC_AT_LOG;
@@ -516,3 +549,57 @@ convert_scan_code(uint16_t scan_code)
return scan_code;
}
const char *
keyboard_get_name(int keyboard)
{
return (keyboard_devices[keyboard].device->name);
}
const char *
keyboard_get_internal_name(int keyboard)
{
return device_get_internal_name(keyboard_devices[keyboard].device);
}
int
keyboard_get_from_internal_name(char *s)
{
int c = 0;
while (keyboard_devices[c].device != NULL) {
if (!strcmp((char *) keyboard_devices[c].device->internal_name, s))
return c;
c++;
}
return 0;
}
int
keyboard_has_config(int keyboard)
{
if (keyboard_devices[keyboard].device == NULL)
return 0;
return (keyboard_devices[keyboard].device->config ? 1 : 0);
}
const device_t *
keyboard_get_device(int keyboard)
{
return (keyboard_devices[keyboard].device);
}
/* Return number of MOUSE types we know about. */
int
keyboard_get_ndev(void)
{
return ((sizeof(keyboard_devices) / sizeof(keyboard_t)) - 1);
}
void
keyboard_add_device(void)
{
device_add(keyboard_devices[keyboard_type].device);
}

File diff suppressed because it is too large Load Diff

View File

@@ -35,62 +35,8 @@
#include <86box/machine.h>
#include <86box/m_xt_t1000.h>
#include <86box/cassette.h>
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/ppi.h>
#include <86box/mem.h>
#include <86box/rom.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_LOCK 0x10
#define STAT_CD 0x08
#define STAT_SYSFLAG 0x04
#define STAT_IFULL 0x02
#define STAT_OFULL 0x01
/* Keyboard Types */
enum {
KBD_TYPE_PC81 = 0,
KBD_TYPE_PC82,
KBD_TYPE_XT82,
KBD_TYPE_XT86,
KBD_TYPE_COMPAQ,
KBD_TYPE_TANDY,
KBD_TYPE_TOSHIBA,
KBD_TYPE_VTECH,
KBD_TYPE_OLIVETTI,
KBD_TYPE_ZENITH,
KBD_TYPE_PRAVETZ,
KBD_TYPE_HYUNDAI,
KBD_TYPE_FE2010,
KBD_TYPE_XTCLONE
};
typedef struct xtkbd_t {
int want_irq;
int blocked;
int tandy;
uint8_t pa;
uint8_t pb;
uint8_t pd;
uint8_t cfg;
uint8_t clock;
uint8_t key_waiting;
uint8_t type;
uint8_t pravetz_flags;
uint8_t cpu_speed;
pc_timer_t send_delay_timer;
} xtkbd_t;
/*XT keyboard has no escape scancodes, and no scancodes beyond 53*/
const scancode scancode_xt[512] = {
// clang-format off
@@ -609,810 +555,66 @@ const scancode scancode_xt[512] = {
// clang-format on
};
static uint8_t key_queue[16];
static int key_queue_start = 0;
static int key_queue_end = 0;
static int is_tandy = 0;
static int is_t1x00 = 0;
static int is_amstrad = 0;
#ifdef ENABLE_KEYBOARD_XT_LOG
int keyboard_xt_do_log = ENABLE_KEYBOARD_XT_LOG;
static void
kbd_log(const char *fmt, ...)
{
va_list ap;
if (keyboard_xt_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define kbd_log(fmt, ...)
#endif
static uint8_t
get_fdd_switch_settings(void)
{
uint8_t fdd_count = 0;
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fdd_get_flags(i))
fdd_count++;
}
if (!fdd_count)
return 0x00;
else
return ((fdd_count - 1) << 6) | 0x01;
}
static uint8_t
get_videomode_switch_settings(void)
{
if (video_is_mda())
return 0x30;
else if (video_is_cga())
return 0x20; /* 0x10 would be 40x25 */
else
return 0x00;
}
static void
kbd_poll(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
timer_advance_u64(&kbd->send_delay_timer, 1000 * TIMER_USEC);
if (!(kbd->pb & 0x40) && (kbd->type != KBD_TYPE_TANDY))
return;
if (kbd->want_irq) {
kbd->want_irq = 0;
kbd->pa = kbd->key_waiting;
kbd->blocked = 1;
picint(2);
#ifdef ENABLE_KEYBOARD_XT_LOG
kbd_log("XTkbd: kbd_poll(): keyboard_xt : take IRQ\n");
#endif
}
if ((key_queue_start != key_queue_end) && !kbd->blocked) {
kbd->key_waiting = key_queue[key_queue_start];
kbd_log("XTkbd: reading %02X from the key queue at %i\n",
kbd->key_waiting, key_queue_start);
key_queue_start = (key_queue_start + 1) & 0x0f;
kbd->want_irq = 1;
}
}
static void
kbd_adddata(uint16_t val)
{
/* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */
if (is_t1x00) {
if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */
t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */
switch (val) {
case 0x45: /* Num Lock => toggle numpad */
t1000_syskey(0x00, 0x00, 0x10);
break;
case 0x47: /* Home => internal display */
t1000_syskey(0x40, 0x00, 0x00);
break;
case 0x49: /* PgDn => turbo on */
t1000_syskey(0x80, 0x00, 0x00);
break;
case 0x4D: /* Right => toggle LCD font */
t1000_syskey(0x00, 0x00, 0x20);
break;
case 0x4F: /* End => external display */
t1000_syskey(0x00, 0x40, 0x00);
break;
case 0x51: /* PgDn => turbo off */
t1000_syskey(0x00, 0x80, 0x00);
break;
case 0x54: /* SysRQ => toggle window */
t1000_syskey(0x00, 0x00, 0x08);
break;
default:
break;
}
} else
t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */
}
key_queue[key_queue_end] = val;
kbd_log("XTkbd: %02X added to key queue at %i\n",
val, key_queue_end);
key_queue_end = (key_queue_end + 1) & 0x0f;
}
void
kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val))
{
uint8_t num_lock = 0;
uint8_t shift_states = 0;
if (!adddata)
return;
keyboard_get_states(NULL, &num_lock, NULL, NULL);
shift_states = keyboard_get_shift() & STATE_LSHIFT;
if (is_amstrad)
num_lock = !num_lock;
/* If NumLock is on, invert the left shift state so we can always check for
the the same way flag being set (and with NumLock on that then means it
is actually *NOT* set). */
if (num_lock)
shift_states ^= STATE_LSHIFT;
switch (val) {
case FAKE_LSHIFT_ON:
/* If NumLock is on, fake shifts are sent when shift is *NOT* presed,
if NumLock is off, fake shifts are sent when shift is pressed. */
if (shift_states) {
/* Send fake shift. */
adddata(num_lock ? 0x2a : 0xaa);
}
break;
case FAKE_LSHIFT_OFF:
if (shift_states) {
/* Send fake shift. */
adddata(num_lock ? 0xaa : 0x2a);
}
break;
default:
adddata(val);
break;
}
}
static void
kbd_adddata_ex(uint16_t val)
{
kbd_adddata_process(val, kbd_adddata);
}
static void
kbd_write(uint16_t port, uint8_t val, void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
uint8_t bit;
uint8_t set;
uint8_t new_clock;
switch (port) {
case 0x61: /* Keyboard Control Register (aka Port B) */
if (!(val & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) {
new_clock = !!(val & 0x40);
if (!kbd->clock && new_clock) {
key_queue_start = key_queue_end = 0;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd_adddata(0xaa);
}
}
kbd->pb = val;
if (!(kbd->pb & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI))
kbd->clock = !!(kbd->pb & 0x40);
ppi.pb = val;
timer_process();
if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) && (cassette != NULL))
pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0);
speaker_update();
speaker_gated = val & 1;
speaker_enable = val & 2;
if (speaker_enable)
was_speaker_enable = 1;
pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1);
if (val & 0x80) {
kbd->pa = 0;
kbd->blocked = 0;
picintc(2);
}
#ifdef ENABLE_KEYBOARD_XT_LOG
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
#endif
break;
case 0x62: /* Switch Register (aka Port C) */
#ifdef ENABLE_KEYBOARD_XT_LOG
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10));
#endif
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Switch register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->pd = (kbd->pd & 0x30) | (val & 0xcf);
}
break;
case 0x63:
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Configuration register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->cfg = val;
}
break;
case 0xc0 ... 0xcf: /* Pravetz Flags */
kbd_log("XTkbd: Port %02X out: %02X\n", port, val);
if (kbd->type == KBD_TYPE_PRAVETZ) {
bit = (port >> 1) & 0x07;
set = (port & 0x01) << bit;
kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set;
}
break;
case 0x1f0:
kbd_log("XTkbd: Port %04X out: %02X\n", port, val);
if (kbd->type == KBD_TYPE_VTECH) {
kbd->cpu_speed = val;
cpu_dynamic_switch(kbd->cpu_speed >> 7);
}
break;
default:
break;
}
}
static uint8_t
kbd_read(uint16_t port, void *priv)
{
const xtkbd_t *kbd = (xtkbd_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x60: /* Keyboard Data Register (aka Port A) */
if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) ||
(kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) ||
(kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))) {
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_HYUNDAI))
ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00);
else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_VTECH))
/* According to Ruud on the PCem forum, this is supposed to
return 0xFF on the XT. */
ret = 0xff;
else if (kbd->type == KBD_TYPE_ZENITH) {
/* Zenith Data Systems Z-151
* SW1 switch settings:
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bit 2-3: base memory size
* bit 1: fpu enable
* bit 0: fdc enable
*/
ret = get_fdd_switch_settings();
ret |= get_videomode_switch_settings();
/* Base memory size should always be 64k */
ret |= 0x0c;
if (hasfpu)
ret |= 0x02;
}
} else
ret = kbd->pa;
break;
case 0x61: /* Keyboard Control Register (aka Port B) */
ret = kbd->pb;
break;
case 0x62: /* Switch Register (aka Port C) */
if (kbd->type == KBD_TYPE_FE2010) {
if (kbd->pb & 0x04) /* PB2 */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
else
ret = kbd->pd >> 4;
} else if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) {
if (kbd->pb & 0x04) /* PB2 */
switch (mem_size + isa_mem_size) {
case 64:
case 48:
case 32:
case 16:
ret = 0x00;
break;
default:
ret = (((mem_size + isa_mem_size) - 64) / 32) & 0x0f;
break;
}
else
ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4;
} else if ((kbd->type == KBD_TYPE_OLIVETTI) ||
(kbd->type == KBD_TYPE_ZENITH)) {
/* Olivetti M19 or Zenith Data Systems Z-151 */
if (kbd->pb & 0x04) /* PB2 */
ret = kbd->pd & 0xbf;
else
ret = kbd->pd >> 4;
} else {
if (kbd->pb & 0x08) /* PB3 */
ret = kbd->pd >> 4;
else
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
ret |= (ppispeakon ? 0x20 : 0);
/* This is needed to avoid error 131 (cassette error).
This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) {
if (cassette == NULL)
ret |= (ppispeakon ? 0x10 : 0);
else
ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0);
}
if (kbd->type == KBD_TYPE_TANDY)
ret |= (tandy1k_eeprom_read() ? 0x10 : 0);
break;
case 0x63: /* Keyboard Configuration Register (aka Port D) */
if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) ||
(kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH))
ret = kbd->pd;
break;
case 0xc0: /* Pravetz Flags */
if (kbd->type == KBD_TYPE_PRAVETZ)
ret = kbd->pravetz_flags;
kbd_log("XTkbd: Port %02X in : %02X\n", port, ret);
break;
case 0x1f0:
if (kbd->type == KBD_TYPE_VTECH)
ret = kbd->cpu_speed;
kbd_log("XTkbd: Port %04X in : %02X\n", port, ret);
break;
default:
break;
}
return ret;
}
static void
kbd_reset(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd->pa = 0x00;
kbd->pb = 0x00;
kbd->pravetz_flags = 0x00;
keyboard_scan = 1;
key_queue_start = 0;
key_queue_end = 0;
}
void
keyboard_set_is_amstrad(int ams)
{
is_amstrad = ams;
}
typedef struct {
int type;
} kbd_t;
static void *
kbd_init(const device_t *info)
{
xtkbd_t *kbd;
kbd_t *dev = (kbd_t *) calloc(1, sizeof(kbd_t));
kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t));
dev->type = info->local;
io_sethandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
keyboard_send = kbd_adddata_ex;
kbd->type = info->local;
if (kbd->type == KBD_TYPE_VTECH)
kbd->cpu_speed = (!!cpu) << 2;
kbd_reset(kbd);
if (kbd->type == KBD_TYPE_PRAVETZ)
io_sethandler(0x00c0, 16,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
if (kbd->type == KBD_TYPE_VTECH)
io_sethandler(0x01f0, 1,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
if (dev->type == KBD_83_KEY)
keyboard_set_table(scancode_xt);
else
keyboard_set_table(scancode_set1);
key_queue_start = key_queue_end = 0;
video_reset(gfxcard[0]);
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) ||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) {
/* DIP switch readout: bit set = OFF, clear = ON. */
if (kbd->type == KBD_TYPE_OLIVETTI)
/* Olivetti M19
* Jumpers J1, J2 - monitor type.
* 01 - mono (high-res)
* 10 - color (low-res, disables 640x400x2 mode)
* 00 - autoswitching
*/
kbd->pd |= 0x00;
else
/* Switches 7, 8 - floppy drives. */
kbd->pd = get_fdd_switch_settings();
/* Switches 5, 6 - video card type */
kbd->pd |= get_videomode_switch_settings();
/* Switches 3, 4 - memory size. */
if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) {
switch (mem_size) {
case 256:
kbd->pd |= 0x00;
break;
case 512:
kbd->pd |= 0x04;
break;
case 576:
kbd->pd |= 0x08;
break;
case 640:
default:
kbd->pd |= 0x0c;
break;
}
} else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_VTECH)) {
switch (mem_size) {
case 64: /* 1x64k */
kbd->pd |= 0x00;
break;
case 128: /* 2x64k */
kbd->pd |= 0x04;
break;
case 192: /* 3x64k */
kbd->pd |= 0x08;
break;
case 256: /* 4x64k */
default:
kbd->pd |= 0x0c;
break;
}
} else if (kbd->type == KBD_TYPE_PC82) {
switch (mem_size) {
#ifdef PC82_192K_3BANK
case 192: /* 3x64k, not supported by stock BIOS due to bugs */
kbd->pd |= 0x08;
break;
#else
case 192: /* 2x64k + 2x32k */
#endif
case 64: /* 4x16k */
case 96: /* 2x32k + 2x16k */
case 128: /* 4x32k */
case 160: /* 2x64k + 2x16k */
case 224: /* 3x64k + 1x32k */
case 256: /* 4x64k */
default:
kbd->pd |= 0x0c;
break;
}
} else { /* really just the PC '81 */
switch (mem_size) {
case 16: /* 1x16k */
kbd->pd |= 0x00;
break;
case 32: /* 2x16k */
kbd->pd |= 0x04;
break;
case 48: /* 3x16k */
kbd->pd |= 0x08;
break;
case 64: /* 4x16k */
default:
kbd->pd |= 0x0c;
break;
}
}
/* Switch 2 - 8087 FPU. */
if (hasfpu)
kbd->pd |= 0x02;
} else if (kbd->type == KBD_TYPE_ZENITH) {
/* Zenith Data Systems Z-151
* SW2 switch settings:
* bit 7: monitor frequency
* bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd)
* bits 0-4: installed memory
*/
kbd->pd = 0x20;
switch (mem_size) {
case 128:
kbd->pd |= 0x02;
break;
case 192:
kbd->pd |= 0x04;
break;
case 256:
kbd->pd |= 0x06;
break;
case 320:
kbd->pd |= 0x08;
break;
case 384:
kbd->pd |= 0x0a;
break;
case 448:
kbd->pd |= 0x0c;
break;
case 512:
kbd->pd |= 0x0e;
break;
case 576:
kbd->pd |= 0x10;
break;
case 640:
default:
kbd->pd |= 0x12;
break;
}
}
timer_add(&kbd->send_delay_timer, kbd_poll, kbd, 1);
keyboard_set_table(scancode_xt);
is_tandy = (kbd->type == KBD_TYPE_TANDY);
is_t1x00 = (kbd->type == KBD_TYPE_TOSHIBA);
is_amstrad = 0;
return kbd;
return dev;
}
static void
kbd_close(void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
/* Stop the timer. */
timer_disable(&kbd->send_delay_timer);
/* Disable scanning. */
keyboard_scan = 0;
keyboard_send = NULL;
io_removehandler(0x0060, 4,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd);
kbd_t *kbd = (kbd_t *) priv;
free(kbd);
}
const device_t keyboard_pc_device = {
.name = "IBM PC Keyboard (1981)",
.internal_name = "keyboard_pc",
.flags = 0,
.local = KBD_TYPE_PC81,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
static const device_config_t keyboard_pc_xt_config[] = {
// clang-format off
{
.name = "keys",
.description = "Keys",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = KBD_83_KEY,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "83", .value = KBD_83_KEY },
{ .description = "101 (ANSI)", .value = KBD_101_KEY },
{ .description = "102 (ISO)", .value = KBD_102_KEY }
},
.bios = { { 0 } }
},
{
.name = "", .description = "", .type = CONFIG_END
}
// clang-format on
};
const device_t keyboard_pc82_device = {
.name = "IBM PC Keyboard (1982)",
.internal_name = "keyboard_pc82",
.flags = 0,
.local = KBD_TYPE_PC82,
const device_t keyboard_pc_xt_device = {
.name = "PC/XT Keyboard",
.internal_name = "keyboard_pc_xt",
.flags = DEVICE_XT_KBC,
.local = 0,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_pravetz_device = {
.name = "Pravetz Keyboard",
.internal_name = "keyboard_pravetz",
.flags = 0,
.local = KBD_TYPE_PRAVETZ,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_device = {
.name = "XT (1982) Keyboard",
.internal_name = "keyboard_xt",
.flags = 0,
.local = KBD_TYPE_XT82,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt86_device = {
.name = "XT (1986) Keyboard",
.internal_name = "keyboard_xt86",
.flags = 0,
.local = KBD_TYPE_XT86,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_compaq_device = {
.name = "Compaq Portable Keyboard",
.internal_name = "keyboard_xt_compaq",
.flags = 0,
.local = KBD_TYPE_COMPAQ,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_tandy_device = {
.name = "Tandy 1000 Keyboard",
.internal_name = "keyboard_tandy",
.flags = 0,
.local = KBD_TYPE_TANDY,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_t1x00_device = {
.name = "Toshiba T1x00 Keyboard",
.internal_name = "keyboard_xt_t1x00",
.flags = 0,
.local = KBD_TYPE_TOSHIBA,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_lxt3_device = {
.name = "VTech Laser Turbo XT Keyboard",
.internal_name = "keyboard_xt_lxt",
.flags = 0,
.local = KBD_TYPE_VTECH,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_olivetti_device = {
.name = "Olivetti XT Keyboard",
.internal_name = "keyboard_xt_olivetti",
.flags = 0,
.local = KBD_TYPE_OLIVETTI,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_zenith_device = {
.name = "Zenith XT Keyboard",
.internal_name = "keyboard_xt_zenith",
.flags = 0,
.local = KBD_TYPE_ZENITH,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_hyundai_device = {
.name = "Hyundai XT Keyboard",
.internal_name = "keyboard_xt_hyundai",
.flags = 0,
.local = KBD_TYPE_HYUNDAI,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xt_fe2010_device = {
.name = "Faraday FE2010 XT Keyboard",
.internal_name = "keyboard_xt_fe2010",
.flags = 0,
.local = KBD_TYPE_FE2010,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xtclone_device = {
.name = "XT (Clone) Keyboard",
.internal_name = "keyboard_xtclone",
.flags = 0,
.local = KBD_TYPE_XTCLONE,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.config = keyboard_pc_xt_config
};

View File

@@ -480,7 +480,7 @@ ltsermouse_update_report_period(mouse_t *dev)
}
static void
ltsermouse_switch_baud_rate(mouse_t *dev, int next_state)
ltsermouse_switch_baud_rate(mouse_t *dev, int next_state, int prompt_off)
{
double word_lens[FORMATS_NUM] = {
[FORMAT_BP1_ABS] = 7.0 + 1.0, /* 7 data bits + even parity */
@@ -517,7 +517,7 @@ ltsermouse_switch_baud_rate(mouse_t *dev, int next_state)
ltsermouse_set_report_period(dev, dev->rps);
if (!dev->continuous && (next_state != STATE_BAUD_RATE)) {
if (dev->prompt)
if (dev->prompt && prompt_off)
ltsermouse_set_prompt_mode(dev, 0);
sermouse_transmit_report(dev, 0);
@@ -569,7 +569,7 @@ ltsermouse_process_command(mouse_t *dev)
dev->buf[0] = 0x06;
sermouse_transmit(dev, 1, 0, 0);
ltsermouse_switch_baud_rate(dev, STATE_BAUD_RATE);
ltsermouse_switch_baud_rate(dev, STATE_BAUD_RATE, 0);
break;
case 0x4a: /* Report Rate Selection commands */
@@ -614,7 +614,7 @@ ltsermouse_process_command(mouse_t *dev)
case 0x58: /* Microsoft Compatible Format (3+1 byte 3-button, from the FreeBSD source code) */
if ((dev->rev >= 0x02) && ((dev->command != 0x58) || (dev->rev > 0x04))) {
dev->format = dev->command & 0x1f;
ltsermouse_switch_baud_rate(dev, sermouse_next_state(dev));
ltsermouse_switch_baud_rate(dev, sermouse_next_state(dev), 0);
}
break;
@@ -706,7 +706,7 @@ ltsermouse_process_data(mouse_t *dev)
dev->bps = 9600;
break;
}
ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT);
ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT, 0);
break;
default:
dev->state = STATE_IDLE;
@@ -744,7 +744,7 @@ sermouse_reset(mouse_t *dev, int callback)
break;
}
ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE);
ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE, 1);
}
static void