device wrote:
I think there are ways to reprogram the clock to generate more higher resolution tics.
DaveYes, there are. I am using a custom timer resolution in my game, here's
what you have to do to
a) set the timer to 1ms resolution
b) keep the DOS clock going correctly nonetheless
Just reprogramming the timer chip without some book-keeping would let
the DOS clock run 18 times as fast. We don't want that... --8<------------------------------------------------------------
typedef void (__interrupt __far* INTFUNCPTR)(void);
INTFUNCPTR oldTimerInterrupt; // Original interrupt handler
volatile long int milliseconds; // Elapsed time in milliseconds
void __interrupt __far timerHandler(void)
{
static unsigned long count=0; // To keep track of original timer ticks ++milliseconds;
count+=1103;
if(count>=65536) // It is now time to call the original handler
{
count-=65536;
_chain_intr(oldTimerInterrupt);
}
else
outp(0x20,0x20); // Acknowledge interrupt
}
void installInterrupt(void)
{
union REGS r;
struct SREGS s;
_disable();
segread(&s);
/* Save old interrupt vector: */
r.h.al=0x08;
r.h.ah=0x35;
int386x(0x21,&r,&r,&s);
oldTimerInterrupt=(INTFUNCPTR)MK_FP(s.es,r.x.ebx);
/* Install new interrupt handler: */
milliseconds=0;
r.h.al=0x08;
r.h.ah=0x25;
s.ds=FP_SEG(timerHandler);
r.x.edx=FP_OFF(timerHandler);
int386x(0x21,&r,&r,&s);
/* Set resolution of timer chip to 1ms: */
outp(0x43,0x36);
outp(0x40,(unsigned char)(1103&0xff));
outp(0x40,(unsigned char)((1103>>8)&0xff));
_enable();
}
void removeInterrupt(void)
{
union REGS r;
struct SREGS s;
_disable();
segread(&s);
/* Re-install original interrupt handler: */
r.h.al=0x08;
r.h.ah=0x25;
s.ds=FP_SEG(oldTimerInterrupt);
r.x.edx=FP_OFF(oldTimerInterrupt);
int386x(0x21,&r,&r,&s);
/* Reset timer chip resolution to 18.2...ms: */
outp(0x43,0x36);
outp(0x40,0x00);
outp(0x40,0x00);
_enable();
}
--8<------------------------------------------------------------
To query the elapsed time in ms, just read the variable milliseconds.
A note: This program is for Watcom C. For other compilers, some
structures and functions (like _enable) might have different names.
Refer to your compiler's manual.
A second note: This program is for Protected Mode using DOS/4G. To
compile it for real mode, just replace all int386 by int86, and all wide registers (like edx) with their short counterparts (like dx). The
program should work fine then.
I hope this helps a bit,
Oliver
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 418 |
Nodes: | 16 (0 / 16) |
Uptime: | 41:51:17 |
Calls: | 8,783 |
Calls today: | 10 |
Files: | 13,296 |
Messages: | 5,964,537 |