- USB keypad now supported (patch from Ben Lunt)

- USB port config option now handled in the pciusb code (the devices "mouse" and
  "keypad" are currently supported)
This commit is contained in:
Volker Ruppert 2005-01-14 18:28:47 +00:00
parent 09420bc8d2
commit 2c001794a2
7 changed files with 150 additions and 58 deletions

View File

@ -516,8 +516,8 @@ floppy_command_delay: 500
# With the mouse type option you can select the type of mouse to emulate.
# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
# on PS/2), 'serial', 'serial_wheel' (one com port requires setting
# 'mode=mouse') and 'usb' (3-button mouse on USB port #1 - requires PCI and
# USB support).
# 'mode=mouse') and 'usb' (3-button mouse - one of the USB ports must be
# connected with the 'mouse' device - requires PCI and USB support).
#
# Examples:
# mouse: enabled=1
@ -649,11 +649,13 @@ keyboard_mapping: enabled=0, map=
#=======================================================================
# USB1:
# This option controls the presence of the USB root hub which is a part
# of the i440FX PCI chipset. If you enable USB and use the mouse option
# 'type=usb' you'll have a 3-button mouse connected to port #1.
# of the i440FX PCI chipset. With the portX option you can connect devices
# to the hub (currently supported: 'mouse' and 'keypad'). If you connect
# the mouse to one of the ports and use the mouse option 'type=usb' you'll
# have a 3-button USB mouse.
#
# Example:
# usb1: enabled=1, ioaddr=0xFF80
# usb1: enabled=1, ioaddr=0xFF80, port1=mouse, port2=keypad
#=======================================================================
#usb1: enabled=1, ioaddr=0xFF80

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: iodev.h,v 1.57 2004-12-31 16:40:36 vruppert Exp $
// $Id: iodev.h,v 1.58 2005-01-14 18:28:46 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -323,10 +323,13 @@ class BOCHSAPI bx_usb_stub_c : public bx_devmodel_c {
virtual void usb_mouse_enable(bx_bool enable) {
STUBFUNC(pciusb, usb_mouse_enable);
}
virtual bx_bool usb_key_enq(Bit32u key) {
virtual bx_bool usb_key_enq(Bit8u *scan_code) {
STUBFUNC(pciusb, usb_key_enq);
return 0;
}
virtual bx_bool usb_keyboard_connected() {
return 0;
}
};
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: keyboard.cc,v 1.99 2004-12-16 19:03:30 vruppert Exp $
// $Id: keyboard.cc,v 1.100 2005-01-14 18:28:46 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -125,7 +125,7 @@ bx_keyb_c::resetinternals(bx_bool powerup)
void
bx_keyb_c::init(void)
{
BX_DEBUG(("Init $Id: keyboard.cc,v 1.99 2004-12-16 19:03:30 vruppert Exp $"));
BX_DEBUG(("Init $Id: keyboard.cc,v 1.100 2005-01-14 18:28:46 vruppert Exp $"));
Bit32u i;
DEV_register_irq(1, "8042 Keyboard controller");
@ -744,6 +744,14 @@ bx_keyb_c::gen_scancode(Bit32u key)
else
scancode=(unsigned char *)scancodes[(key&0xFF)][BX_KEY_THIS s.kbd_controller.current_scancodes_set].make;
#if BX_SUPPORT_PCIUSB
if (DEV_usb_keyboard_connected()) {
// if we have a keyboard/keypad installed, we need to call its handler first
if (DEV_usb_key_enq(scancode)) return;
}
#endif
if (BX_KEY_THIS s.kbd_controller.scancodes_translate) {
// Translate before send
Bit8u escaped=0x00;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb.cc,v 1.18 2004-12-30 14:50:37 vruppert Exp $
// $Id: pciusb.cc,v 1.19 2005-01-14 18:28:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -172,8 +172,8 @@ bx_pciusb_c::reset(unsigned type)
BX_USB_THIS last_connect = 0xFF;
BX_USB_THIS global_reset = 0;
BX_USB_THIS set_address_stk = 0;
BX_USB_THIS saved_key = 0;
BX_USB_THIS packet_key = 0;
memset(BX_USB_THIS saved_key, 0, 8);
memset(BX_USB_THIS key_pad_packet, 0, 8);
// mouse packet stuff
BX_USB_THIS mouse_delayed_dx = 0;
@ -223,22 +223,44 @@ bx_pciusb_c::reset(unsigned type)
for (j=0; j<USB_CUR_DEVS; j++)
memset(&BX_USB_THIS hub[i].device[j], 0, sizeof(USB_DEVICE));
BX_USB_THIS keyboard_connected = 0;
// include the device(s) initialize code
#include "pciusb_devs.h"
// Check to see if we should connect the devices and other initialization items
if (bx_options.Omouse_type->get() == BX_MOUSE_TYPE_USB) {
// If one of the devices is a mouse, enable it if the user has stated so in the rc file.
usb_set_connect_status(USB_DEV_TYPE_MOUSE, bx_options.Omouse_enabled->get());
}
//if (bx_options.usb_keypad.Oenabled->get()) { // Key Pad
if (0) { // Key Pad disabled for now
// If one of the devices is a keypad, enable it if the user has stated so in the rc file.
usb_set_connect_status(USB_DEV_TYPE_KEYPAD, 1);
init_device(0, bx_options.usb[0].Oport1->getptr());
init_device(1, bx_options.usb[0].Oport2->getptr());
}
void
bx_pciusb_c::init_device(Bit8u port, char *devname)
{
Bit8u type = USB_DEV_TYPE_NONE;
bx_bool connected = 0;
if (!strlen(devname)) return;
if (!strcmp(devname, "mouse")) {
type = USB_DEV_TYPE_MOUSE;
connected = bx_options.Omouse_enabled->get();
if (bx_options.Omouse_type->get() != BX_MOUSE_TYPE_USB) {
BX_ERROR(("USB mouse present, but other mouse type configured"));
}
} else if (!strcmp(devname, "keypad")) {
type = USB_DEV_TYPE_KEYPAD;
connected = 1;
BX_USB_THIS keyboard_connected = 1;
} else {
BX_PANIC(("unknown USB device: %s", devname));
return;
}
for (int i=0; i<USB_CUR_DEVS; i++) {
if (BX_USB_THIS hub[0].device[i].dev_type == type) {
BX_USB_THIS hub[0].usb_port[port].device_num = i;
}
}
usb_set_connect_status(type, connected);
}
void
@ -771,8 +793,7 @@ void bx_pciusb_c::DoTransfer(struct TD *td) {
switch (protocol) {
case 1: // keypad
memset(device_buffer, 0, 8);
device_buffer[2] = BX_USB_THIS packet_key;
memcpy(device_buffer, BX_USB_THIS key_pad_packet, 8);
BX_MEM_WRITE_PHYSICAL(td->dword3, cnt, device_buffer);
BX_USB_THIS set_status(td, 0, 0, 0, 0, 0, 0, cnt-1);
@ -1514,13 +1535,29 @@ bx_pciusb_c::usb_mouse_enq(int delta_x, int delta_y, int delta_z, unsigned butto
}
bx_bool
bx_pciusb_c::usb_key_enq(Bit32u key)
bx_pciusb_c::usb_key_enq(Bit8u *scan_code)
{
// BX_INFO(("scan code: len = %i 0x%02x 0x%02x 0x%02x", strlen((char *) scan_code), scan_code[0], scan_code[1], scan_code[2]));
// return 0;
bx_bool is_break_code = 0;
Bit8u our_scan_code[8];
memset(our_scan_code, 0, 8);
int os = 0;
for (int s=0; s<8; s++) {
if ((scan_code[s] == 0xF0) && ((s == 0) || ((s == 1) && (scan_code[0] == 0xE0)))) {
is_break_code = 1;
} else {
if (!(our_scan_code[os++] = scan_code[s])) break;
}
}
// if it is the break code of the saved key, then clear our packet key.
if ((key & BX_KEY_RELEASED) && (BX_USB_THIS saved_key == (key & ~BX_KEY_RELEASED))) {
BX_USB_THIS packet_key = 0;
BX_USB_THIS saved_key = key;
if (is_break_code && !memcmp(BX_USB_THIS saved_key, our_scan_code, 8)) {
memset(BX_USB_THIS saved_key, 0, 8);
memset(BX_USB_THIS key_pad_packet, 0, 8);
return 1; // tell the keyboard handler that we used it, and to return with out processing key
}
@ -1537,12 +1574,18 @@ bx_pciusb_c::usb_key_enq(Bit32u key)
for (int l=0; l<dev->function.device_config[k].interfaces && !fnd; l++) {
if ((dev->function.device_config[k].Interface[l].protocol == 1)
&& dev->function.device_config[k].Interface[l].lookup_cnt) {
for (int m=0; m<dev->function.device_config[k].Interface[l].lookup_cnt; m++) {
if (dev->function.device_config[k].Interface[l].lookup[m].key == key) {
BX_USB_THIS packet_key = dev->function.device_config[k].Interface[l].lookup[m].keypad;
fnd = 1;
break;
// Only do this if the keypad is in the configured state
if (dev->state == STATE_CONFIGURED) {
for (int m=0; m<dev->function.device_config[k].Interface[l].lookup_cnt; m++) {
if (!memcmp(dev->function.device_config[k].Interface[l].lookup[m].scan_code, our_scan_code, 8)) {
memcpy(BX_USB_THIS key_pad_packet, dev->function.device_config[k].Interface[l].lookup[m].keypad_packet, 8);
fnd = 1;
break;
}
}
} else {
memset(BX_USB_THIS saved_key, 0, 8);
return 0; // if keypad is not configured, it can't send scan codes.
}
}
}
@ -1550,13 +1593,31 @@ bx_pciusb_c::usb_key_enq(Bit32u key)
}
}
}
BX_USB_THIS saved_key = key;
if (!fnd) BX_USB_THIS packet_key = 0;
if (!fnd) {
memset(BX_USB_THIS key_pad_packet, 0, 8);
memset(BX_USB_THIS saved_key, 0, 8);
} else {
memcpy(BX_USB_THIS saved_key, our_scan_code, 8);
// print a debug line to the log file
char bx_debug_code[128] = "";
char value[8];
for (unsigned i=0; i<strlen((char *) our_scan_code); i++) {
sprintf(value, "0x%02x", our_scan_code[i]);
if (i) strcat(bx_debug_code, " ");
strcat(bx_debug_code, value);
}
BX_DEBUG(("Re-routing scan code (%s) to USB keypad", bx_debug_code));
}
// tell the keyboard handler whether we used it or not. (0 = no, 1 = yes and keyboard.cc ignores keystoke)
return fnd;
}
bx_bool
bx_pciusb_c::usb_keyboard_connected()
{
return BX_USB_THIS keyboard_connected;
}
#endif // BX_SUPPORT_PCI && BX_SUPPORT_PCIUSB

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb.h,v 1.7 2004-12-24 21:38:01 vruppert Exp $
// $Id: pciusb.h,v 1.8 2005-01-14 18:28:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -95,8 +95,8 @@ struct REQUEST_PACKET {
#define KEYPAD_LEN 128
struct KEYPAD {
Bit32u key;
Bit8u keypad;
Bit8u scan_code[8];
Bit8u keypad_packet[8];
};
#define USB_DEV_TYPE_NONE 0
@ -355,7 +355,8 @@ public:
virtual void reset(unsigned);
virtual void usb_mouse_enq(int delta_x, int delta_y, int delta_z, unsigned button_state);
virtual void usb_mouse_enable(bx_bool enable);
virtual bx_bool usb_key_enq(Bit32u key);
virtual bx_bool usb_key_enq(Bit8u *scan_code);
virtual bx_bool usb_keyboard_connected();
private:
@ -373,8 +374,8 @@ private:
Bit8s mouse_z;
Bit8u b_state;
Bit32u saved_key;
Bit8u packet_key;
Bit8u saved_key[8];
Bit8u key_pad_packet[8];
static void set_irq_level(bx_bool level);
Bit8u *device_buffer;
@ -383,6 +384,9 @@ private:
Bit8u set_address[128];
bx_bool last_connect;
bx_bool keyboard_connected;
static void init_device(Bit8u port, char *devname);
static void usb_set_connect_status(int type, bx_bool connected);
static void usb_timer_handler(void *);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pciusb_devs.h,v 1.2 2004-12-19 09:59:40 vruppert Exp $
// $Id: pciusb_devs.h,v 1.3 2005-01-14 18:28:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 MandrakeSoft S.A.
@ -44,7 +44,6 @@
#if USB_CYPRESS
BX_USB_THIS hub[0].device[0].connect_status = 0;
BX_USB_THIS hub[0].usb_port[0].device_num = 0;
BX_USB_THIS hub[0].device[0].dev_type = USB_DEV_TYPE_MOUSE;
BX_USB_THIS hub[0].device[0].state = STATE_DEFAULT;
@ -180,7 +179,6 @@
#if USB_KEYPAD
BX_USB_THIS hub[0].device[1].connect_status = 0;
BX_USB_THIS hub[0].usb_port[1].device_num = 1;
BX_USB_THIS hub[0].device[1].dev_type = USB_DEV_TYPE_KEYPAD;
BX_USB_THIS hub[0].device[1].state = STATE_DEFAULT;
@ -229,11 +227,25 @@
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[0].subclass = 1;
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[0].protocol = 1;
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[0].str_indx = 5;
// this interface has a key conversion table of len = 18
struct KEYPAD dev0_int0[KEYPAD_LEN] = {
{ 0x2A, 0x45 }, { 0x53, 0x11 }, { 0x54, 0x65 }, { 0x55, 0x64 }, { 0x56, 0x53 }, { 0x57, 0x52 },
{ 0x58, 0x63 }, { 0x59, 0x54 }, { 0x5A, 0x55 }, { 0x5B, 0x56 }, { 0x5C, 0x57 }, { 0x5D, 0x5E },
{ 0x5E, 0x58 }, { 0x5F, 0x59 }, { 0x60, 0x5A }, { 0x61, 0x5B }, { 0x62, 0x5C }, { 0x63, 0x5D },
{ { 0x6C, }, { 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 7
{ { 0x6B, }, { 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 4
{ { 0x69, }, { 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 1
{ { 0x70, }, { 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 0
{ { 0xE0, 0x4A, }, { 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // /
{ { 0x75, }, { 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 8
{ { 0x73, }, { 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 5
{ { 0x72, }, { 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 2
{ { 0x7C, }, { 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // *
{ { 0x7D, }, { 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 9
{ { 0x74, }, { 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 6
{ { 0x7A, }, { 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // 3
{ { 0x71, }, { 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // -
{ { 0x7B, }, { 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // +
{ { 0x79, }, { 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // .
{ { 0xE0, 0x5A }, { 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00 } }, // Enter
};
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[0].lookup_cnt = 18;
memcpy(&BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[0].lookup, &dev0_int0, sizeof(struct KEYPAD) * KEYPAD_LEN);
@ -281,7 +293,7 @@
// this interface has no key conversion table
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[1].lookup_cnt = 0;
memset(&BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[1].lookup, 0, sizeof(struct KEYPAD) * KEYPAD_LEN);
// HID descriptor #2
// 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x32, 0x00 // hid descriptor
BX_USB_THIS hub[0].device[1].function.device_config[0].Interface[1].dev_hid_descript.size = 9;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: plugin.h,v 1.37 2004-12-31 16:40:36 vruppert Exp $
// $Id: plugin.h,v 1.38 2005-01-14 18:28:45 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// This file provides macros and types needed for plugins. It is based on
@ -205,14 +205,16 @@ extern "C" {
#define DEV_bus_mouse_enq(dx, dy, dz, state) \
(bx_devices.pluginBusMouse->bus_mouse_enq(dx, dy, 0, state))
///////// USB mouse macro
///////// USB device macros
#if BX_SUPPORT_PCIUSB
#define DEV_usb_mouse_enq(dx, dy, dz, state) \
#define DEV_usb_mouse_enq(dx, dy, dz, state) \
(bx_devices.pluginPciUSBAdapter->usb_mouse_enq(dx, dy, dz, state))
#define DEV_usb_mouse_enable(enable) \
#define DEV_usb_mouse_enable(enable) \
(bx_devices.pluginPciUSBAdapter->usb_mouse_enable(enable))
#define DEV_usb_key_enq(key) \
(bx_devices.pluginPciUSBAdapter->usb_key_enq(key))
#define DEV_usb_key_enq(scan_code) \
(bx_devices.pluginPciUSBAdapter->usb_key_enq(scan_code))
#define DEV_usb_keyboard_connected() \
(bx_devices.pluginPciUSBAdapter->usb_keyboard_connected())
#endif
//////// Memory macros