Beispiel #1
0
static VOID XmsLocalDisableA20(VOID)
{
    UCHAR Result = XMS_STATUS_SUCCESS;

    /* Disable A20 only if we can do so, otherwise make the caller believe we disabled it */
    if (!CanChangeA20) goto Quit;

    /* If the count is already zero, fail */
    if (A20EnableCount == 0) goto Fail;

    --A20EnableCount;

    /* The count is zero so disable A20 */
    if (A20EnableCount == 0)
        EmulatorSetA20(FALSE); // Result = XMS_STATUS_SUCCESS;
    else
        Result = XMS_STATUS_A20_STILL_ENABLED;

Quit:
    setAX(0x0001); /* Line successfully disabled */
    setBL(Result);
    return;

Fail:
    setAX(0x0000); /* Line failed to be disabled */
    setBL(XMS_STATUS_A20_ERROR);
    return;
}
Beispiel #2
0
static VOID XmsLocalEnableA20(VOID)
{
    /* Enable A20 only if we can do so, otherwise make the caller believe we enabled it */
    if (!CanChangeA20) goto Quit;

    /* The count is zero so enable A20 */
    if (A20EnableCount == 0) EmulatorSetA20(TRUE);

    ++A20EnableCount;

Quit:
    setAX(0x0001); /* Line successfully enabled */
    setBL(XMS_STATUS_SUCCESS);
    return;
}
Beispiel #3
0
static VOID WINAPI PS2WritePort(ULONG 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);
    }
}