Make DOSVM_Wait work in protected mode.
Replace SHOULD_PEND macro with a function.
This commit is contained in:
parent
6551965003
commit
0b79a6e7c3
|
@ -91,14 +91,33 @@ static struct _DOSEVENT *pending_event, *current_event;
|
||||||
static int sig_sent;
|
static int sig_sent;
|
||||||
static HANDLE event_notifier;
|
static HANDLE event_notifier;
|
||||||
|
|
||||||
#define SHOULD_PEND(x) \
|
|
||||||
(x && ((!current_event) || (x->priority < current_event->priority)))
|
/***********************************************************************
|
||||||
|
* DOSVM_HasPendingEvents
|
||||||
|
*
|
||||||
|
* Return true if there are pending events that are not
|
||||||
|
* blocked by currently active event.
|
||||||
|
*/
|
||||||
|
static BOOL DOSVM_HasPendingEvents( void )
|
||||||
|
{
|
||||||
|
if (!pending_event)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!current_event)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (pending_event->priority < current_event->priority)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DOSVM_SendQueuedEvent(CONTEXT86 *context)
|
static void DOSVM_SendQueuedEvent(CONTEXT86 *context)
|
||||||
{
|
{
|
||||||
LPDOSEVENT event = pending_event;
|
LPDOSEVENT event = pending_event;
|
||||||
|
|
||||||
if (SHOULD_PEND(event)) {
|
if (DOSVM_HasPendingEvents()) {
|
||||||
/* remove from "pending" list */
|
/* remove from "pending" list */
|
||||||
pending_event = event->next;
|
pending_event = event->next;
|
||||||
/* process event */
|
/* process event */
|
||||||
|
@ -118,7 +137,7 @@ static void DOSVM_SendQueuedEvent(CONTEXT86 *context)
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!SHOULD_PEND(pending_event)) {
|
if (!DOSVM_HasPendingEvents()) {
|
||||||
TRACE("clearing Pending flag\n");
|
TRACE("clearing Pending flag\n");
|
||||||
CLR_PEND(context);
|
CLR_PEND(context);
|
||||||
}
|
}
|
||||||
|
@ -268,13 +287,31 @@ static void DOSVM_ProcessMessage(MSG *msg)
|
||||||
*/
|
*/
|
||||||
void WINAPI DOSVM_Wait( CONTEXT86 *waitctx )
|
void WINAPI DOSVM_Wait( CONTEXT86 *waitctx )
|
||||||
{
|
{
|
||||||
if (SHOULD_PEND(pending_event))
|
if (DOSVM_HasPendingEvents())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FIXME: This does not work in protected mode DOS programs.
|
|
||||||
* FIXME: Critical section locking is broken.
|
* FIXME: Critical section locking is broken.
|
||||||
*/
|
*/
|
||||||
CONTEXT86 context = *waitctx;
|
CONTEXT86 context = *waitctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If DOSVM_Wait is called from protected mode we emulate
|
||||||
|
* interrupt reflection and convert context into real mode context.
|
||||||
|
* This is actually the correct thing to do as long as DOSVM_Wait
|
||||||
|
* is only called from those interrupt functions that DPMI reflects
|
||||||
|
* to real mode.
|
||||||
|
*
|
||||||
|
* FIXME: Need to think about where to place real mode stack.
|
||||||
|
* FIXME: If DOSVM_Wait calls are nested stack gets corrupted.
|
||||||
|
* Can this really happen?
|
||||||
|
*/
|
||||||
|
if (!ISV86(&context))
|
||||||
|
{
|
||||||
|
context.EFlags |= 0x00020000;
|
||||||
|
context.SegSs = 0xffff;
|
||||||
|
context.Esp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
IF_SET(&context);
|
IF_SET(&context);
|
||||||
SET_PEND(&context);
|
SET_PEND(&context);
|
||||||
context.SegCs = 0;
|
context.SegCs = 0;
|
||||||
|
@ -473,7 +510,7 @@ void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val)
|
||||||
(*event->relay)(NULL,event->data);
|
(*event->relay)(NULL,event->data);
|
||||||
free(event);
|
free(event);
|
||||||
|
|
||||||
if (pending_event) {
|
if (DOSVM_HasPendingEvents()) {
|
||||||
/* another event is pending, which we should probably
|
/* another event is pending, which we should probably
|
||||||
* be able to process now */
|
* be able to process now */
|
||||||
TRACE("another event pending, setting flag\n");
|
TRACE("another event pending, setting flag\n");
|
||||||
|
|
Loading…
Reference in New Issue