PS2M.cpp revision 892ba2c161e62c8e858f2fcf299c38951e330d39
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * PS2M - PS/2 auxiliary device (mouse) emulation.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (C) 2007-2013 Oracle Corporation
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * available from http://www.virtualbox.org. This file is free software;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * General Public License (GPL) as published by the Free Software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * References:
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The Undocumented PC (2nd Ed.), Frank van Gilluwe, Addison-Wesley, 1996.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * IBM TrackPoint System Version 4.0 Engineering Specification, 1999.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * ELAN Microelectronics eKM8025 USB & PS/2 Mouse Controller, 2006.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The auxiliary device commands are very similar to keyboard commands.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Most keyboard commands which do not specifically deal with the keyboard
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * (enable, disable, reset) have identical counterparts.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The code refers to 'auxiliary device' and 'mouse'; these terms are not
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * quite interchangeable. 'Auxiliary device' is used when referring to the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * generic PS/2 auxiliary device interface and 'mouse' when referring to
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * a mouse attached to the auxiliary port.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The basic modes of operation are reset, stream, and remote. Those are
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * mutually exclusive. Stream and remote modes can additionally have wrap
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * mode enabled.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The auxiliary device sends unsolicited data to the host only when it is
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * both in stream mode and enabled. Otherwise it only responds to commands.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * There are three report packet formats supported by the emulated device. The
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * standard three-byte PS/2 format (with middle button support), IntelliMouse
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * four-byte format with added scroll wheel, and IntelliMouse Explorer four-byte
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * format with reduced scroll wheel range but two additional buttons. Note that
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * the first three bytes of the report are always the same.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Upon reset, the mouse is always in the standard PS/2 mode. A special 'knock'
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * sequence can be used to switch to ImPS/2 or ImEx mode. Three consecutive
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Set Sampling Rate (0F3h) commands with arguments 200, 100, 80 switch to ImPS/2
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * mode. While in ImPS/2 or PS/2 mode, three consecutive Set Sampling Rate
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * commands with arguments 200, 200, 80 switch to ImEx mode. The Read ID (0F2h)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * command will report the currently selected protocol.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Standard PS/2 pointing device three-byte report packet format:
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * |Bit/byte| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * | Byte 1 | Y ovfl | X ovfl | Y sign | X sign | Sync | M btn | R btn | L btn |
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * | Byte 2 | X movement delta (two's complement) |
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * | Byte 3 | Y movement delta (two's complement) |
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * - The sync bit is always set. It allows software to synchronize data packets
ae20b83f0c94402a3e3ac021c3d4e5f827e4905cvboxsync * as the X/Y position data typically does not have bit 4 set.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The overflow bits are set if motion exceeds accumulator range. We use the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * maximum range (effectively 9 bits) and do not set the overflow bits.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - Movement in the up/right direction is defined as having positive sign.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * IntelliMouse PS/2 (ImPS/2) fourth report packet byte:
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * |Bit/byte| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * | Byte 4 | Z movement delta (two's complement) |
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * - The valid range for Z delta values is only -8/+7, i.e. 4 bits.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * IntelliMouse Explorer (ImEx) fourth report packet byte:
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
8c7f1eb426ed2259c4ed882d80af2666b2490867vboxsync * |Bit/byte| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
8c7f1eb426ed2259c4ed882d80af2666b2490867vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
8c7f1eb426ed2259c4ed882d80af2666b2490867vboxsync * | Byte 4 | 0 | 0 | Btn 5 | Btn 4 | Z mov't delta (two's complement) |
8c7f1eb426ed2259c4ed882d80af2666b2490867vboxsync * +--------+--------+--------+--------+--------+--------+--------+--------+--------+
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Header Files *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Defined Constants And Macros *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** @name Auxiliary device commands sent by the system.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define ACMD_SET_SCALE_11 0xE6 /* Set 1:1 scaling. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define ACMD_SET_SCALE_21 0xE7 /* Set 2:1 scaling. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define ACMD_REQ_STATUS 0xE9 /* Get device status. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define ACMD_READ_REMOTE 0xEB /* Read remote data. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define ACMD_SET_WRAP 0xEE /* Set wrap (echo) mode. */
c618f4d0eeea6061ff8270e8f7023a999bd0bb91vboxsync#define ACMD_SET_SAMP_RATE 0xF3 /* Set sampling rate. */
c618f4d0eeea6061ff8270e8f7023a999bd0bb91vboxsync#define ACMD_ENABLE 0xF4 /* Enable (streaming mode). */
c618f4d0eeea6061ff8270e8f7023a999bd0bb91vboxsync#define ACMD_DISABLE 0xF5 /* Disable (streaming mode). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** @name Auxiliary device responses sent to the system.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Define a simple PS/2 input device queue. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync typedef struct { \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* Internal mouse queue sizes. The input queue is relatively large,
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * but the command queue only needs to handle a few bytes.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Structures and Typedefs *
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync*******************************************************************************/
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync/* Auxiliary device special modes of operation. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsynctypedef enum {
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync/* Auxiliary device operational state. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsynctypedef enum {
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync AUX_STATE_SCALING = RT_BIT(4), /* 2:1 scaling in effect. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync AUX_STATE_ENABLED = RT_BIT(5), /* Reporting enabled in stream mode. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync AUX_STATE_REMOTE = RT_BIT(6) /* Remote mode (reports on request). */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync/* Protocols supported by the PS/2 mouse. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsynctypedef enum {
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync PS2M_PROTO_PS2STD = 0, /* Standard PS/2 mouse protocol. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync PS2M_PROTO_IMPS2 = 3, /* IntelliMouse PS/2 protocol. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync PS2M_PROTO_IMEX = 4 /* IntelliMouse Explorer protocol. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync/* Protocol selection 'knock' states. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsynctypedef enum {
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync * The PS/2 auxiliary device instance data.
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsynctypedef struct PS2M
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Pointer to parent device (keyboard controller). */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Operational state. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Configured sampling rate. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Configured resolution. */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Currently processed command (if any). */
486d3fda5cadcf6d8357df872455cdd8796b3556vboxsync /** Set if the throttle delay is active. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Set if the throttle delay is active. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Operational mode. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Currently used protocol. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Currently used protocol. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Buffer holding mouse events to be sent to the host. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Command response queue (priority). */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Accumulated horizontal movement. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Accumulated vertical movement. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Accumulated Z axis movement. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Accumulated button presses. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Instantaneous button data. */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync /** Throttling delay in milliseconds. */
e218a78cf91e0a6e295bffe1998e96b308c5a13avboxsync /** The device critical section protecting everything - R3 Ptr */
e218a78cf91e0a6e295bffe1998e96b308c5a13avboxsync /** Command delay timer - R3 Ptr. */
e218a78cf91e0a6e295bffe1998e96b308c5a13avboxsync /** Interrupt throttling timer - R3 Ptr. */
e218a78cf91e0a6e295bffe1998e96b308c5a13avboxsync /** Command delay timer - RC Ptr. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Interrupt throttling timer - RC Ptr. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Command delay timer - R0 Ptr. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Interrupt throttling timer - R0 Ptr. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Mouse port - LUN#1.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @implements PDMIBASE
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @implements PDMIMOUSEPORT
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** The base interface for the mouse port. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** The keyboard port base interface. */
a000f6190af85455eefaa1097deaeea087cfc5e5vboxsync /** The base interface of the attached mouse driver. */
a000f6190af85455eefaa1097deaeea087cfc5e5vboxsync /** The keyboard interface of the attached mouse driver. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Global Variables *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
90bb13bdf70379f91f6aeb334f70287a5096fb02vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Internal Functions *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Clear a queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pQ Pointer to the queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Add a byte to a queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pQ Pointer to the queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param val The byte to store.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void ps2kInsertQueue(GeneriQ *pQ, uint8_t val)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Check if queue is full. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlowFunc(("queue %p full (%d entries)\n", pQ, pQ->cUsed));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Insert data and update circular buffer write position. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlowFunc(("inserted 0x%02X into queue %p\n", val, pQ));
d7fe26caad92e0d13017738ab94de18e37be91b4vboxsync * Save a queue state.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pSSM SSM handle to write the state to.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pQ Pointer to the queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void ps2kSaveQueue(PSSMHANDLE pSSM, GeneriQ *pQ)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Only save the number of items. Note that the read/write
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * positions aren't saved as they will be rebuilt on load.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlow(("Storing %d items from queue %p\n", cItems, pQ));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Save queue data - only the bytes actually used (typically zero). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync for (i = pQ->rpos; cItems-- > 0; i = (i + 1) % pQ->cSize)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Load a queue state.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pSSM SSM handle to read the state from.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pQ Pointer to the queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @return int VBox status/error code.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic int ps2kLoadQueue(PSSMHANDLE pSSM, GeneriQ *pQ)
d7fe26caad92e0d13017738ab94de18e37be91b4vboxsync /* On load, always put the read pointer at zero. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlow(("Loading %d items to queue %p\n", pQ->cUsed, pQ));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync AssertMsgFailed(("Saved size=%u, actual=%u\n", pQ->cUsed, pQ->cSize));
4f007e159d64d64366398032617896c3a982fa42vboxsync /* Recalculate queue positions and load data in one go. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* Report a change in status down (or is it up?) the driver chain. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void ps2mSetDriverState(PPS2M pThis, bool fEnabled)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync pDrv->pfnReportModes(pDrv, fEnabled, false, false);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* Reset the pointing device. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync ps2kInsertQueue((GeneriQ *)&pThis->cmdQ, ARSP_BAT_OK);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync //@todo: move to its proper home!
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#endif /* IN_RING3 */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Retrieve a byte from a queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pQ Pointer to the queue.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @param pVal Pointer to storage for the byte.
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync * @return int VINF_TRY_AGAIN if queue is empty,
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsync * VINF_SUCCESS if a byte was read.
4d4f336b656d46f8d301603114bb99ce635aafc0vboxsyncstatic int ps2kRemoveQueue(GeneriQ *pQ, uint8_t *pVal)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlowFunc(("removed 0x%02X from queue %p\n", *pVal, pQ));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlowFunc(("Sampling rate %u, throttle delay %u ms\n", pThis->u8SampleRate, pThis->uThrottleDelay));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Standard protocol, reporting disabled, resolution 2, 1:1 scaling. */
0547b5d21ca43e39c3b6fba8cd9988b1338d61d0vboxsync /* Sample rate 100 reports per second. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Event queue, eccumulators, and button status bits are cleared. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync pThis->iAccumX = pThis->iAccumY = pThis->iAccumZ = pThis->fAccumB = pThis->fCurrB = 0;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* Handle the sampling rate 'knock' sequence which selects protocol. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void ps2mRateProtocolKnock(PPS2M pThis, uint8_t rate)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogRelFlow(("PS2M: Switching mouse to ImPS/2 protocol.\n"));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogRelFlow(("PS2M: Switching mouse to ImEx protocol.\n"));
9577536266a8da7dbbe29fd3be840cbfc0dc9721vboxsync /* Fall through! */
ead20681ed6c34b0fc835c3e6c19b8034856653avboxsync/* Three-button event mask. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define PS2M_STD_BTN_MASK (RT_BIT(0) | RT_BIT(1) | RT_BIT(2))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* Report accumulated movement and button presses, then clear the accumulators. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic void ps2mReportAccumulatedEvents(PPS2M pThis, GeneriQ *pQueue, bool fAccumBtns)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t fBtnState = fAccumBtns ? pThis->fAccumB : pThis->fCurrB;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Clamp the accumulated delta values to the allowed range. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Start with the sync bit and buttons 1-3. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Set the X/Y sign bits. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Send the standard 3-byte packet (always the same). */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Add fourth byte if extended protocol is in use. */
89f5aff9eff63826c9b171cc7fdb9dc1513fa09dvboxsync /* Z value uses 4 bits; buttons 4/5 in bits 4 and 5. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Clear the movement accumulators. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync pThis->iAccumX = pThis->iAccumY = pThis->iAccumZ = 0;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* Clear accumulated button state only when it's being used. */
if (fAccumBtns)
bool fHandled = true;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
switch (cmd)
case ACMD_SET_SCALE_11:
case ACMD_SET_SCALE_21:
case ACMD_REQ_STATUS:
case ACMD_SET_STREAM:
case ACMD_READ_REMOTE:
case ACMD_RESET_WRAP:
case ACMD_SET_WRAP:
case ACMD_SET_REMOTE:
case ACMD_READ_ID:
case ACMD_ENABLE:
#ifdef IN_RING3
case ACMD_DISABLE:
case ACMD_SET_DEFAULT:
case ACMD_RESEND:
case ACMD_RESET:
#ifdef IN_RING3
case ACMD_SET_RES:
case ACMD_SET_SAMP_RATE:
case ACMD_SET_RES:
case ACMD_SET_SAMP_RATE:
fHandled = false;
if (fHandled)
case ACMD_INVALID_1:
case ACMD_INVALID_2:
case ACMD_INVALID_3:
case ACMD_INVALID_4:
case ACMD_INVALID_5:
case ACMD_INVALID_6:
case ACMD_INVALID_7:
case ACMD_INVALID_8:
case ACMD_INVALID_9:
case ACMD_INVALID_10:
return VINF_SUCCESS;
int rc;
return rc;
#ifdef IN_RING3
if (uHaveEvents)
///@todo Might want a PS2MCompleteCommand() to push last response, clear command, and kick the KBC...
static DECLCALLBACK(void) ps2mInfoState(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
return NULL;
if (dx < 0)
if (dy < 0)
return rc;
return VINF_SUCCESS;
int rc;
rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->Mouse.IBase, &pThis->Mouse.pDrvBase, "Mouse Port");
Log(("%s/%d: warning: no driver attached to LUN #1!\n", pDevIns->pReg->szName, pDevIns->iInstance));
return rc;
int rc;
return rc;
int rc;
return rc;
return rc;
return rc;