Start source tree (final, I hope!) restructuration. Part 1/X
[reactos.git] / reactos / subsystems / ntvdm / hardware / ps2.c
diff --git a/reactos/subsystems/ntvdm/hardware/ps2.c b/reactos/subsystems/ntvdm/hardware/ps2.c
deleted file mode 100644 (file)
index b7e6c13..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * COPYRIGHT:       GPL - See COPYING in the top level directory
- * PROJECT:         ReactOS Virtual DOS Machine
- * FILE:            ps2.c
- * PURPOSE:         PS/2 controller emulation
- * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
- *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
- */
-
-/* INCLUDES *******************************************************************/
-
-#define NDEBUG
-
-#include "emulator.h"
-#include "io.h"
-#include "ps2.h"
-#include "pic.h"
-
-/* PRIVATE VARIABLES **********************************************************/
-
-#define BUFFER_SIZE 32
-
-typedef struct _PS2_PORT
-{
-    BOOLEAN IsEnabled;
-
-    BOOLEAN QueueEmpty;
-    BYTE    Queue[BUFFER_SIZE];
-    UINT    QueueStart;
-    UINT    QueueEnd;
-    HANDLE  QueueMutex;
-
-    LPVOID             Param;
-    PS2_DEVICE_CMDPROC DeviceCommand;
-} PS2_PORT, *PPS2_PORT;
-
-/*
- * Port 1: Keyboard
- * Port 2: Mouse
- */
-#define PS2_PORTS  2
-static PS2_PORT Ports[PS2_PORTS];
-
-#define PS2_DEFAULT_CONFIG  0x47
-static BYTE ControllerConfig = PS2_DEFAULT_CONFIG;
-static BYTE ControllerCommand = 0x00;
-
-static BYTE StatusRegister = 0x00;
-// static BYTE InputBuffer  = 0x00; // PS/2 Input  Buffer
-static BYTE OutputBuffer = 0x00; // PS/2 Output Buffer
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-static VOID PS2SendCommand(PPS2_PORT Port, BYTE Command)
-{
-    if (!Port->IsEnabled) return;
-
-    /* Call the device command */
-    if (Port->DeviceCommand) Port->DeviceCommand(Port->Param, Command);
-}
-
-static BYTE WINAPI PS2ReadPort(USHORT Port)
-{
-    if (Port == PS2_CONTROL_PORT)
-    {
-        /* Be sure bit 2 is always set */
-        StatusRegister |= 1 << 2;
-
-        // FIXME: Should clear bits 6 and 7 because there are
-        // no timeouts and no parity errors.
-
-        return StatusRegister;
-    }
-    else if (Port == PS2_DATA_PORT)
-    {
-        /*
-         * If there is something to read (response byte from the
-         * controller or data from a PS/2 device), read it.
-         */
-        if (StatusRegister &   (1 << 0)) // || StatusRegister &   (1 << 5) for second PS/2 port
-            StatusRegister &= ~(1 << 0); //    StatusRegister &= ~(1 << 5);
-
-        // FIXME: We may check there whether there is data latched in
-        // PS2 ports 1 or 2 (keyboard or mouse) and retrieve it there...
-
-        /* Always return the available byte stored in the output buffer */
-        return OutputBuffer;
-    }
-
-    return 0x00;
-}
-
-static VOID WINAPI PS2WritePort(USHORT Port, BYTE Data)
-{
-    if (Port == PS2_CONTROL_PORT)
-    {
-        switch (Data)
-        {
-            /* Read configuration byte */
-            case 0x20:
-            {
-                OutputBuffer = ControllerConfig;
-                StatusRegister |= (1 << 0); // There is something to read
-                break;
-            }
-
-            /* Write configuration byte */
-            case 0x60:
-            /* Write controller output port */
-            case 0xD1:
-            /* Write to the first PS/2 port output buffer */
-            case 0xD2:
-            /* Write to the second PS/2 port output buffer */
-            case 0xD3:
-            /* Write to the second PS/2 port input buffer */
-            case 0xD4:
-            {
-                /* These commands require a response */
-                ControllerCommand = Data;
-                StatusRegister |= (1 << 3); // This is a controller command
-                break;
-            }
-
-            /* Disable second PS/2 port */
-            case 0xA7:
-            {
-                Ports[1].IsEnabled = FALSE;
-                break;
-            }
-
-            /* Enable second PS/2 port */
-            case 0xA8:
-            {
-                Ports[1].IsEnabled = TRUE;
-                break;
-            }
-
-            /* Test second PS/2 port */
-            case 0xA9:
-            {
-                OutputBuffer = 0x00; // Success code
-                StatusRegister |= (1 << 0); // There is something to read
-                break;
-            }
-
-            /* Test PS/2 controller */
-            case 0xAA:
-            {
-                OutputBuffer = 0x55; // Success code
-                StatusRegister |= (1 << 0); // There is something to read
-                break;
-            }
-
-            /* Test first PS/2 port */
-            case 0xAB:
-            {
-                OutputBuffer = 0x00; // Success code
-                StatusRegister |= (1 << 0); // There is something to read
-                break;
-            }
-
-            /* Disable first PS/2 port */
-            case 0xAD:
-            {
-                Ports[0].IsEnabled = FALSE;
-                break;
-            }
-
-            /* Enable first PS/2 port */
-            case 0xAE:
-            {
-                Ports[0].IsEnabled = TRUE;
-                break;
-            }
-
-            /* Read controller output port */
-            case 0xD0:
-            {
-                // TODO: Not implemented
-                break;
-            }
-
-            /* CPU Reset */
-            case 0xF0:
-            case 0xF2:
-            case 0xF4:
-            case 0xF6:
-            case 0xF8:
-            case 0xFA:
-            case 0xFC:
-            case 0xFE:
-            {
-                /* Stop the VDM */
-                EmulatorTerminate();
-                break;
-            }
-        }
-    }
-    else if (Port == PS2_DATA_PORT)
-    {
-        /* Check if the controller is waiting for a response */
-        if (StatusRegister & (1 << 3)) // If we have data for the controller
-        {
-            StatusRegister &= ~(1 << 3);
-
-            /* Check which command it was */
-            switch (ControllerCommand)
-            {
-                /* Write configuration byte */
-                case 0x60:
-                {
-                    ControllerConfig = Data;
-                    break;
-                }
-
-                /* Write controller output */
-                case 0xD1:
-                {
-                    /* Check if bit 0 is unset */
-                    if (!(Data & (1 << 0)))
-                    {
-                        /* CPU disabled - Stop the VDM */
-                        EmulatorTerminate();
-                    }
-
-                    /* Update the A20 line setting */
-                    EmulatorSetA20(Data & (1 << 1));
-
-                    break;
-                }
-
-                /* Push the data byte into the first PS/2 port queue */
-                case 0xD2:
-                {
-                    PS2QueuePush(0, Data);
-                    break;
-                }
-
-                /* Push the data byte into the second PS/2 port queue */
-                case 0xD3:
-                {
-                    PS2QueuePush(1, Data);
-                    break;
-                }
-
-                /*
-                 * Send a command to the second PS/2 port (by default
-                 * it is a command for the first PS/2 port)
-                 */
-                case 0xD4:
-                {
-                    PS2SendCommand(&Ports[1], Data);
-                    break;
-                }
-            }
-
-            return;
-        }
-
-        /* By default, send a command to the first PS/2 port */
-        PS2SendCommand(&Ports[0], Data);
-    }
-}
-
-static BOOLEAN PS2PortQueueRead(BYTE PS2Port)
-{
-    BOOLEAN Result = TRUE;
-    PPS2_PORT Port;
-
-    if (PS2Port >= PS2_PORTS) return FALSE;
-    Port = &Ports[PS2Port];
-
-    if (!Port->IsEnabled) return FALSE;
-
-    /* Make sure the queue is not empty (fast check) */
-    if (Port->QueueEmpty)
-    {
-        /* Only the keyboard should have its last data latched */
-        // FIXME: Alternatively this can be done in PS2ReadPort when
-        // we read PS2_DATA_PORT. What is the best solution??
-        if (PS2Port == 0)
-        {
-            OutputBuffer = Port->Queue[(Port->QueueStart - 1) % BUFFER_SIZE];
-        }
-
-        return FALSE;
-    }
-
-    WaitForSingleObject(Port->QueueMutex, INFINITE);
-
-    /*
-     * Recheck whether the queue is not empty (it may
-     * have changed after having grabbed the mutex).
-     */
-    if (Port->QueueEmpty)
-    {
-        Result = FALSE;
-        goto Done;
-    }
-
-    /* Get the data */
-    OutputBuffer = Port->Queue[Port->QueueStart];
-    StatusRegister |= (1 << 0); // There is something to read
-    // Sometimes StatusRegister |= (1 << 5); for the second PS/2 port
-
-    /* Remove the value from the queue */
-    Port->QueueStart++;
-    Port->QueueStart %= BUFFER_SIZE;
-
-    /* Check if the queue is now empty */
-    if (Port->QueueStart == Port->QueueEnd)
-        Port->QueueEmpty = TRUE;
-
-Done:
-    ReleaseMutex(Port->QueueMutex);
-    return Result;
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID PS2SetDeviceCmdProc(BYTE PS2Port, LPVOID Param, PS2_DEVICE_CMDPROC DeviceCommand)
-{
-    if (PS2Port >= PS2_PORTS) return;
-
-    Ports[PS2Port].Param         = Param;
-    Ports[PS2Port].DeviceCommand = DeviceCommand;
-}
-
-// PS2SendToPort
-BOOLEAN PS2QueuePush(BYTE PS2Port, BYTE Data)
-{
-    BOOLEAN Result = TRUE;
-    PPS2_PORT Port;
-
-    if (PS2Port >= PS2_PORTS) return FALSE;
-    Port = &Ports[PS2Port];
-
-    if (!Port->IsEnabled) return FALSE;
-
-    WaitForSingleObject(Port->QueueMutex, INFINITE);
-
-    /* Check if the queue is full */
-    if (!Port->QueueEmpty && (Port->QueueStart == Port->QueueEnd))
-    {
-        Result = FALSE;
-        goto Done;
-    }
-
-    /* Insert the value in the queue */
-    Port->Queue[Port->QueueEnd] = Data;
-    Port->QueueEnd++;
-    Port->QueueEnd %= BUFFER_SIZE;
-
-    /* The queue is not empty anymore */
-    Port->QueueEmpty = FALSE;
-
-/*
-    // Get the data
-    OutputBuffer = Port->Queue[Port->QueueStart];
-    StatusRegister |= (1 << 0); // There is something to read
-    // FIXME: Sometimes StatusRegister |= (1 << 5); for the second PS/2 port
-
-    if (PS2Port == 0)
-        PicInterruptRequest(1);
-    else if (PS2Port == 1)
-        PicInterruptRequest(12);
-*/
-
-Done:
-    ReleaseMutex(Port->QueueMutex);
-    return Result;
-}
-
-VOID GenerateIrq1(VOID)
-{
-    /* Generate an interrupt if interrupts for the first PS/2 port are enabled */
-    if (ControllerConfig & 0x01)
-    {
-        /* Generate an IRQ 1 if there is data ready in the output queue */
-        if (PS2PortQueueRead(0)) PicInterruptRequest(1);
-    }
-}
-
-VOID GenerateIrq12(VOID)
-{
-    /* Generate an interrupt if interrupts for the second PS/2 port are enabled */
-    if (ControllerConfig & 0x02)
-    {
-        /* Generate an IRQ 12 if there is data ready in the output queue */
-        if (PS2PortQueueRead(1)) PicInterruptRequest(12);
-    }
-}
-
-BOOLEAN PS2Initialize(VOID)
-{
-    /* Initialize the PS/2 ports */
-    Ports[0].IsEnabled  = TRUE;
-    Ports[0].QueueEmpty = TRUE;
-    Ports[0].QueueStart = 0;
-    Ports[0].QueueEnd   = 0;
-    Ports[0].QueueMutex = CreateMutex(NULL, FALSE, NULL);
-
-    Ports[1].IsEnabled  = TRUE;
-    Ports[1].QueueEmpty = TRUE;
-    Ports[1].QueueStart = 0;
-    Ports[1].QueueEnd   = 0;
-    Ports[1].QueueMutex = CreateMutex(NULL, FALSE, NULL);
-
-    /* Register the I/O Ports */
-    RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
-    RegisterIoPort(PS2_DATA_PORT   , PS2ReadPort, PS2WritePort);
-
-    return TRUE;
-}
-
-VOID PS2Cleanup(VOID)
-{
-    CloseHandle(Ports[1].QueueMutex);
-    CloseHandle(Ports[0].QueueMutex);
-}
-
-/* EOF */