Exemplo n.º 1
0
static
inline
VOID
NTAPI
Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
{
    UCHAR Opcode;
    INT ProcedureCallCount = 0;

    /* Main execution loop */
    do
    {
        /* Check if this is a new instruction */
        if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;

        /* Perform an instruction fetch */
        if (!Fast486FetchByte(State, &Opcode))
        {
            /* Exception occurred */
            State->PrefixFlags = 0;
            continue;
        }

        // TODO: Check for CALL/RET to update ProcedureCallCount.

        if (Fast486OpcodeHandlers[Opcode] != NULL)
        {
            /* Call the opcode handler */
            Fast486OpcodeHandlers[Opcode](State, Opcode);
        }
        else
        {
            /* This is not a valid opcode */
            Fast486Exception(State, FAST486_EXCEPTION_UD);
        }

        if (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix)
        {
            /* This is a prefix, go to the next instruction immediately */
            continue;
        }

        /* A non-prefix opcode has been executed, reset the prefix flags */
        State->PrefixFlags = 0;

        /*
         * Check if there is an interrupt to execute, or a hardware interrupt signal
         * while interrupts are enabled.
         */
        if (State->IntStatus == FAST486_INT_EXECUTE)
        {
            FAST486_IDT_ENTRY IdtEntry;

            /* Get the interrupt vector */
            if (Fast486GetIntVector(State, State->PendingIntNum, &IdtEntry))
            {
                /* Perform the interrupt */
                Fast486InterruptInternal(State,
                                         IdtEntry.Selector,
                                         MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
                                         IdtEntry.Type);

                /* Restore the prefix flags, which would be set to OPSIZE for 32-bit real mode */
                State->PrefixFlags = 0;
            }

            /* Clear the interrupt status */
            State->IntStatus = FAST486_INT_NONE;
        }
        else if (State->Flags.If
                 && (State->IntAckCallback != NULL)
                 && (State->IntStatus == FAST486_INT_SIGNAL))
        {
            /* Acknowledge the interrupt to get the number */
            State->PendingIntNum = State->IntAckCallback(State);

            /* Set the interrupt status to execute on the next instruction */
            State->IntStatus = FAST486_INT_EXECUTE;
        }
        else if (State->IntStatus == FAST486_INT_DELAYED)
        {
            /* Restore the old state */
            State->IntStatus = FAST486_INT_EXECUTE;
        }
    }
    while ((Command == FAST486_CONTINUE)
           || (Command == FAST486_STEP_OVER && ProcedureCallCount > 0)
           || (Command == FAST486_STEP_OUT && ProcedureCallCount >= 0)
           || (Fast486OpcodeHandlers[Opcode] == Fast486OpcodePrefix));
}
Exemplo n.º 2
0
VOID
FASTCALL
Fast486ExceptionWithErrorCode(PFAST486_STATE State,
                              FAST486_EXCEPTIONS ExceptionCode,
                              ULONG ErrorCode)
{
    FAST486_IDT_ENTRY IdtEntry;

    /* Increment the exception count */
    State->ExceptionCount++;

    /* Check if the exception occurred more than once */
    if (State->ExceptionCount > 1)
    {
        /* Then this is a double fault */
        ExceptionCode = FAST486_EXCEPTION_DF;
    }

    /* Check if this is a triple fault */
    if (State->ExceptionCount == 3)
    {
        /* Reset the CPU */
        Fast486Reset(State);
        return;
    }

    /* Restore the IP to the saved IP */
    State->InstPtr = State->SavedInstPtr;

    if (!Fast486GetIntVector(State, ExceptionCode, &IdtEntry))
    {
        /*
         * If this function failed, that means Fast486Exception
         * was called again, so just return in this case.
         */
        return;
    }

    /* Perform the interrupt */
    if (!Fast486InterruptInternal(State,
                                  IdtEntry.Selector,
                                  MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
                                  IdtEntry.Type))
    {
        /*
         * If this function failed, that means Fast486Exception
         * was called again, so just return in this case.
         */
        return;
    }

    if (EXCEPTION_HAS_ERROR_CODE(ExceptionCode)
        && (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
    {
        /* Push the error code */
        if (!Fast486StackPush(State, ErrorCode))
        {
            /*
             * If this function failed, that means Fast486Exception
             * was called again, so just return in this case.
             */
            return;
        }
    }

    /* Reset the exception count */
    State->ExceptionCount = 0;
}