189 lines
3 KiB
C
189 lines
3 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* Digital Sound Interface Kit (DSIK)
|
||
|
* Version 2.00
|
||
|
*
|
||
|
* by Carlos Hasan
|
||
|
*
|
||
|
* Filename: timer.c
|
||
|
* Version: Revision 1.1
|
||
|
*
|
||
|
* Language: WATCOM C
|
||
|
* Environment: IBM PC (DOS/4GW)
|
||
|
*
|
||
|
* Description: Timer interrupt services.
|
||
|
*
|
||
|
* Revision History:
|
||
|
* ----------------
|
||
|
*
|
||
|
* Revision 1.1 94/11/16 10:48:42 chv
|
||
|
* Added VGA vertical retrace synchronization code
|
||
|
*
|
||
|
* Revision 1.0 94/10/28 22:45:47 chv
|
||
|
* Initial revision
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include <STDLIB.H>
|
||
|
#include <CONIO.H>
|
||
|
#include <DOS.H>
|
||
|
#include "timer.h"
|
||
|
|
||
|
|
||
|
static void (interrupt far *BiosTimer)(void) = NULL;
|
||
|
static void (*UserTimer)(void);
|
||
|
static long TimerCount, TimerSpeed, TimerSync;
|
||
|
|
||
|
|
||
|
void timerstub1(void)
|
||
|
{
|
||
|
}
|
||
|
static void WaitVR(void)
|
||
|
{
|
||
|
while (inp(0x3da) & 8) ;
|
||
|
while (!(inp(0x3da) & 8)) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void StartTimer2(void)
|
||
|
{
|
||
|
outp(0x61,inp(0x61) | 0x01);
|
||
|
outp(0x43,0xb4);
|
||
|
outp(0x42,0x00);
|
||
|
outp(0x42,0x00);
|
||
|
}
|
||
|
|
||
|
|
||
|
static int ReadTimer2(void)
|
||
|
{
|
||
|
int n;
|
||
|
|
||
|
outp(0x43,0xb0);
|
||
|
n = inp(0x42);
|
||
|
n += inp(0x42) << 8;
|
||
|
return 0x10000L - n;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int GetSyncTicks(void)
|
||
|
{
|
||
|
int n,Ticks,Delta;
|
||
|
|
||
|
for (n = 0; n < 16; n++)
|
||
|
{
|
||
|
_disable();
|
||
|
WaitVR();
|
||
|
StartTimer2();
|
||
|
WaitVR();
|
||
|
Ticks = Delta = ReadTimer2();
|
||
|
WaitVR();
|
||
|
StartTimer2();
|
||
|
WaitVR();
|
||
|
Delta -= ReadTimer2();
|
||
|
_enable();
|
||
|
if (Delta >= -64 && Delta <= +64) return Ticks;
|
||
|
}
|
||
|
return TICKS(70);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void interrupt TimerHandler(void)
|
||
|
{
|
||
|
static int TimerSem = 0;
|
||
|
|
||
|
if (TimerSem==0)
|
||
|
{
|
||
|
TimerSem++;
|
||
|
outp(0x20,0x20);
|
||
|
_enable();
|
||
|
if (TimerSync)
|
||
|
{
|
||
|
WaitVR();
|
||
|
outp(0x43,0x30);
|
||
|
outp(0x40,TimerSpeed & 0xff);
|
||
|
outp(0x40,TimerSpeed >> 8);
|
||
|
}
|
||
|
(*UserTimer)();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
outp(0x20,0x20);
|
||
|
_enable();
|
||
|
}
|
||
|
if ((TimerCount+=TimerSpeed)>=0x10000)
|
||
|
{
|
||
|
TimerCount-=0x10000;
|
||
|
(*BiosTimer)();
|
||
|
}
|
||
|
if (TimerSem)
|
||
|
TimerSem--;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void IdleTimer(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
void dInitTimer(void)
|
||
|
{
|
||
|
if (!BiosTimer)
|
||
|
{
|
||
|
UserTimer = IdleTimer;
|
||
|
BiosTimer = _dos_getvect(0x08);
|
||
|
_dos_setvect(0x08,TimerHandler);
|
||
|
dSetTimerSpeed(0x10000);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void dDoneTimer(void)
|
||
|
{
|
||
|
if (BiosTimer)
|
||
|
{
|
||
|
dSetTimerSpeed(0x10000);
|
||
|
_dos_setvect(0x08,BiosTimer);
|
||
|
BiosTimer = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void dSetTimerSpeed(int Speed)
|
||
|
{
|
||
|
if (BiosTimer)
|
||
|
{
|
||
|
TimerSync = !(TimerSpeed = Speed);
|
||
|
if (TimerSync)
|
||
|
{
|
||
|
TimerSpeed = GetSyncTicks() - 1024;
|
||
|
outp(0x43,0x30);
|
||
|
}
|
||
|
else outp(0x43,0x36);
|
||
|
outp(0x40,TimerSpeed & 0xff);
|
||
|
outp(0x40,TimerSpeed >> 8);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void dStartTimer(TimerProc Timer, int Speed)
|
||
|
{
|
||
|
if (BiosTimer)
|
||
|
{
|
||
|
UserTimer = Timer;
|
||
|
dSetTimerSpeed(Speed);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void dStopTimer(void)
|
||
|
{
|
||
|
if (BiosTimer)
|
||
|
{
|
||
|
UserTimer = IdleTimer;
|
||
|
dSetTimerSpeed(0x10000);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void timerstub2(void)
|
||
|
{
|
||
|
}
|