Mail Archives: djgpp/1993/07/13/22:57:20
Hi:
Here is the timer subroutines I use. The original subroutines are for
Turbo-C. I modify them to make them work with djgpp.
You can find the original version in M_SEC12.ZIP at SIMTEL20 mirror sites.
These subroutines DO NOT affect system timing.
The time between start and stop must be less than one hour.
Allow multiple read_timer() calls between timer_on() and timer_off().
Usage:
#include "timer.h"
.....
timer_on(); /* Start timer */
.....
start = read_timer();
.....
stop = read_timer();
timer_off();
time_passed = elapsed_time(start,stop); /* unit = msec */
count_passed = elapsed_count(start,stop); /* unit = clock pulse */
/*
time_passed is equal to (count_passed / TIMER_MILLI_COUNT)
*/
-- Jih-Shin Ho
-----------------------------
#ifndef _TIMER_H
#define _TIMER_H
/* timer.h
* Include file defining the timer routines.
* Include this file in any program using them.
*/
#define TIMER_COUNT 1193181u /* Clock freq. = 1.193181 MHz */
#define TIMER_MILLI_COUNT 1193u
/*Calculate time elapsed (in milliseconds) between Start and Stop*/
unsigned int elapsed_time(unsigned int start, unsigned int stop);
/*Reprogram the timer chip to allow 1 millisecond resolution*/
extern void timer_on(void);
/*Restore the timer chip to its normal state*/
extern void timer_off(void);
/*Read the timer */
extern unsigned int read_timer(void);
extern unsigned int elapsed_count(unsigned int start, unsigned int stop);
#endif
----------------------
/*
;timer.s
;Assembly language functions extracted from TIMER.C
;and recoded in *real* assembly language.
;(Too many incompatibilities in all the different
;implementations of inline assembly language ;-)
;
;David Kirschbaum
;Toad Hall
;
;Modified for DJGPP by Jih-Shin Ho, 1993
; u7711501 AT bicmos DOT ee DOT nctu DOT edu DOT tw
*/
.text
.align 2,0x90
.globl _timer_on
.globl _timer_off
.globl _read_timer
.globl _elapsed_time
.globl _elapsed_count
/* ;void timer_on(void) */
_timer_on:
movb $0x34,%al
jmp LCommon ;/* common to return */
/* ;void timer_off(void) */
_timer_off:
movb $0x36,%al ;/* outp(0x043,0x036); */
LCommon:
movw $0x43,%dx
outb %al,%dx
jmp L1
L1:
movw $0x40,%dx ;/* outp(0x040,0x000); */
xorw %ax,%ax
outb %al,%dx
jmp L2
L2:
outb %al,%dx ;/* outp(0x040,0x000); */
ret
.align 2,0x90
/* ;unsigned long read_timer(void) */
_read_timer:
xorl %eax,%eax
movl %eax,%edx
movl %eax,%ecx
outb %al,$0x43 ;/* Latch timer 0 */
movw (0xe000046c),%dx
inb $0x40,%al ;/* Counter --> CX */
movb %al,%cl ;/* LSB in CL */
inb $0x40,%al
movb %al,%ch ;/* MSB in CH */
notw %cx ;/* Need ascending counter */
movw %dx,%ax
shll $16,%eax
orl %ecx,%eax
ret
.bss
.lcomm flag,1
.text
.align 2,0x90
/* unsigned int elapsed_time(start,stop) */
_elapsed_count:
movb $0,flag
jmp L4
.align 2,0x90
_elapsed_time:
movb $1,flag
L4:
movl 8(%esp),%edx ;/* stop */
movl 4(%esp),%ecx ;/* start */
movl %edx,%eax
subl %ecx,%eax
jae L3
movl $-1,%eax
subl %ecx,%eax
addl %edx,%eax
incl %eax
movl %eax,%ecx
andl $0xffff0000,%ecx
cmpl $0xffff0000,%ecx
jne L3
andl $0xffff,%eax
L3:
testb $1,flag
jz L5
movl $1193,%ecx
xorl %edx,%edx
divl %ecx
L5:
ret
- Raw text -