mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
7f740cbb04
Added support for a 55Hz system timer, letting DOS apps calibrate their delay loops and such. Calls INSTR_EmulateInstruction for instruction emulation (principally I/O port access). Added macro V86_FLAG.
211 lines
5.5 KiB
C
211 lines
5.5 KiB
C
/*
|
|
* SYSTEM DLL routines
|
|
*
|
|
* Copyright 1996 Alexandre Julliard
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
#include <sys/timeb.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include "callback.h"
|
|
#include "windows.h"
|
|
#include "miscemu.h"
|
|
#include "dosexe.h"
|
|
#include "vga.h"
|
|
#include "selectors.h"
|
|
#include "sig_context.h"
|
|
#include "debug.h"
|
|
|
|
typedef struct
|
|
{
|
|
FARPROC16 callback; /* NULL if not in use */
|
|
INT32 rate;
|
|
INT32 ticks;
|
|
} SYSTEM_TIMER;
|
|
|
|
#define NB_SYS_TIMERS 8
|
|
#define SYS_TIMER_RATE 54925
|
|
|
|
static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
|
|
static int SYS_NbTimers = 0;
|
|
static BOOL32 SYS_TimersDisabled = FALSE;
|
|
|
|
/***********************************************************************
|
|
* SYSTEM_TimerTick
|
|
* FIXME: It is a very bad idea to call 16bit code in a signal handler:
|
|
* If the signal reached us in 16 bit code, we could have a broken
|
|
* %FS, which is in turned saved into the single global
|
|
* CALLTO16_Current_fs temporary storage, so a single misplaced
|
|
* signal crashes the whole WINE process.
|
|
* This needs more thought. -MM
|
|
*/
|
|
static HANDLER_DEF(SYSTEM_TimerTick)
|
|
{
|
|
int i;
|
|
HANDLER_INIT();
|
|
|
|
for (i = 0; i < NB_SYS_TIMERS; i++)
|
|
{
|
|
if (!SYS_Timers[i].callback) continue;
|
|
if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
|
|
{
|
|
SYS_Timers[i].ticks += SYS_Timers[i].rate;
|
|
|
|
if (SYS_Timers[i].callback == (FARPROC16)DOSMEM_Tick) {
|
|
DOSMEM_Tick();
|
|
} else
|
|
if (SYS_Timers[i].callback == (FARPROC16)MZ_Tick) {
|
|
MZ_Tick(i+1);
|
|
} else
|
|
if (SYS_Timers[i].callback == (FARPROC16)VGA_Poll) {
|
|
VGA_Poll();
|
|
} else
|
|
Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SYSTEM_StartTicks
|
|
*
|
|
* Start the system tick timer.
|
|
*/
|
|
static void SYSTEM_StartTicks(void)
|
|
{
|
|
static BOOL32 handler_installed = FALSE;
|
|
|
|
if (!handler_installed)
|
|
{
|
|
handler_installed = TRUE;
|
|
SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
|
|
}
|
|
#ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
|
|
{
|
|
struct itimerval vt_timer;
|
|
|
|
vt_timer.it_interval.tv_sec = 0;
|
|
vt_timer.it_interval.tv_usec = 54929;
|
|
vt_timer.it_value = vt_timer.it_interval;
|
|
setitimer( ITIMER_REAL, &vt_timer, NULL );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* SYSTEM_StopTicks
|
|
*
|
|
* Stop the system tick timer.
|
|
*/
|
|
static void SYSTEM_StopTicks(void)
|
|
{
|
|
#ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
|
|
struct itimerval vt_timer;
|
|
|
|
vt_timer.it_interval.tv_sec = 0;
|
|
vt_timer.it_interval.tv_usec = 0;
|
|
vt_timer.it_value = vt_timer.it_interval;
|
|
setitimer( ITIMER_REAL, &vt_timer, NULL );
|
|
#endif
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* InquireSystem (SYSTEM.1)
|
|
*
|
|
* Note: the function always takes 2 WORD arguments, contrary to what
|
|
* "Undocumented Windows" says.
|
|
*/
|
|
DWORD WINAPI InquireSystem( WORD code, WORD arg )
|
|
{
|
|
WORD drivetype;
|
|
|
|
switch(code)
|
|
{
|
|
case 0: /* Get timer resolution */
|
|
return SYS_TIMER_RATE;
|
|
|
|
case 1: /* Get drive type */
|
|
drivetype = GetDriveType16( arg );
|
|
return MAKELONG( drivetype, drivetype );
|
|
|
|
case 2: /* Enable one-drive logic */
|
|
FIXME(system, "Case %d: set single-drive %d not supported\n", code, arg );
|
|
return 0;
|
|
}
|
|
WARN(system, "Unknown code %d\n", code );
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* CreateSystemTimer (SYSTEM.2)
|
|
*/
|
|
WORD WINAPI CreateSystemTimer( WORD rate, FARPROC16 callback )
|
|
{
|
|
int i;
|
|
|
|
/* FIXME: HACK: do not create system timers due to problems mentioned
|
|
* above, except DOSMEM_Tick(), MZ_Tick(), and VGA_Poll().
|
|
*/
|
|
if ((callback!=(FARPROC16)DOSMEM_Tick)&&
|
|
(callback!=(FARPROC16)MZ_Tick)&&
|
|
(callback!=(FARPROC16)VGA_Poll)) {
|
|
FIXME(system,"are currently broken, returning 0.\n");
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < NB_SYS_TIMERS; i++)
|
|
if (!SYS_Timers[i].callback) /* Found one */
|
|
{
|
|
SYS_Timers[i].rate = (UINT32)rate * 1000;
|
|
if (SYS_Timers[i].rate < SYS_TIMER_RATE)
|
|
SYS_Timers[i].rate = SYS_TIMER_RATE;
|
|
SYS_Timers[i].ticks = SYS_Timers[i].rate;
|
|
SYS_Timers[i].callback = callback;
|
|
if ((++SYS_NbTimers == 1) && !SYS_TimersDisabled)
|
|
SYSTEM_StartTicks();
|
|
return i + 1; /* 0 means error */
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* KillSystemTimer (SYSTEM.3)
|
|
*
|
|
* Note: do not confuse this function with USER.182
|
|
*/
|
|
WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
|
|
{
|
|
if (!timer || (timer > NB_SYS_TIMERS)) return timer; /* Error */
|
|
SYS_Timers[timer-1].callback = NULL;
|
|
if ((!--SYS_NbTimers) && !SYS_TimersDisabled) SYSTEM_StopTicks();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* EnableSystemTimers (SYSTEM.4)
|
|
*/
|
|
void WINAPI EnableSystemTimers(void)
|
|
{
|
|
SYS_TimersDisabled = FALSE;
|
|
if (SYS_NbTimers) SYSTEM_StartTicks();
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* DisableSystemTimers (SYSTEM.5)
|
|
*/
|
|
void WINAPI DisableSystemTimers(void)
|
|
{
|
|
SYS_TimersDisabled = TRUE;
|
|
if (SYS_NbTimers) SYSTEM_StopTicks();
|
|
}
|