/*
- * COPYRIGHT: GPL - See COPYING in the top level directory
- * PROJECT: 386/486 CPU Emulation Library
- * FILE: soft386.c
- * PURPOSE: Functions meant for use by the host.
- * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Soft386 386/486 CPU Emulation Library
+ * soft386.c
+ *
+ * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* INCLUDES *******************************************************************/
/* Main execution loop */
do
{
+ /* Check if this is a new instruction */
+ if (State->PrefixFlags == 0)
+ {
+ State->SavedInstPtr = State->InstPtr;
+
+ /* Check if interrupts are enabled and there is an interrupt pending */
+ if (State->Flags.If && State->HardwareInt)
+ {
+ SOFT386_IDT_ENTRY IdtEntry;
+
+ /* Get the interrupt vector */
+ if (Soft386GetIntVector(State, State->PendingIntNum, &IdtEntry))
+ {
+ /* Perform the interrupt */
+ Soft386InterruptInternal(State,
+ IdtEntry.Selector,
+ MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
+ IdtEntry.Type);
+ }
+
+ /* Clear the interrupt pending flag */
+ State->HardwareInt = FALSE;
+ }
+ }
+
/* Perform an instruction fetch */
if (!Soft386FetchByte(State, &Opcode)) continue;
/* A non-prefix opcode has been executed, reset the prefix flags */
State->PrefixFlags = 0;
}
+ else
+ {
+ /* This is a prefix, go to the next instruction immediately */
+ continue;
+ }
/* Increment the time stamp counter */
State->TimeStampCounter++;
}
while ((Command == SOFT386_CONTINUE)
|| (Command == SOFT386_STEP_OVER && ProcedureCallCount > 0)
- || (Command == SOFT386_STEP_OUT && ProcedureCallCount >= 0));
+ || (Command == SOFT386_STEP_OUT && ProcedureCallCount >= 0)
+ || (Soft386OpcodeHandlers[Opcode] == Soft386OpcodePrefix));
}
/* PUBLIC FUNCTIONS ***********************************************************/
NTAPI
Soft386Interrupt(PSOFT386_STATE State, UCHAR Number)
{
- // TODO: NOT IMPLEMENTED!!!
- UNIMPLEMENTED;
+ /* Set the hardware interrupt flag */
+ State->HardwareInt = TRUE;
+ State->PendingIntNum = Number;
}
VOID
State->GeneralRegs[SOFT386_REG_ESP].Long = Offset;
}
+VOID
+NTAPI
+Soft386SetSegment(PSOFT386_STATE State,
+ SOFT386_SEG_REGS Segment,
+ USHORT Selector)
+{
+ /* Call the internal function */
+ Soft386LoadSegment(State, Segment, Selector);
+}
/* EOF */