[comp.lang.pascal] How do I determine the clock speed?

dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) (11/30/90)

Can anyone point me to or provide me with some code which will determine the
clock speed?

Thanks in advance,

Daniel Lewart
d-lewart@uiuc.edu

felton@eng3.UUCP (Ed Felton) (12/06/90)

Daniel S. Lewart writes:
  Can anyone point me to or provide me with some code which will determine the
  clock speed?
  
  Thanks in advance,

  Daniel Lewart
  d-lewart@uiuc.edu

I mailed this out, Then realized that others might like to see this also:
To: dslg0849@uxa.cso.uiuc.edu
Subject: Re: How do I determine the clock speed?
Newsgroups: comp.lang.pascal
In-Reply-To: <1990Nov30.121028.98@ux1.cso.uiuc.edu>
Organization: SCI Technology, Inc., Huntsville, Al.

In article <1990Nov30.121028.98@ux1.cso.uiuc.edu> you write:
} Can anyone point me to or provide me with some code which will determine the
} clock speed?
}
} Thanks in advance,
}
} Daniel Lewart
} d-lewart@uiuc.edu


Boy! are you lucky.  Just two weeks ago, I had to figure this out.  Included 
below is some code I wrote (intermediate form for testing purposes, Final code
is many K, and depends on many other things) for MASM and MSC.

First is the MASM routine, which executes a fixed number of machine cycles,
and returns the number of clock ticks it took.
------8<------------------------ CUT HERE ----8<-----------------------------
;****************************************************************************;
;*                                                                          *;
;*  Description:  This file contains the low-level functions                *;
;*  required for general usage within the diagnostics                       *;
;*							                    *; 
;*  Medium Model Code						            *;
;*                                                                          *;
;*  Functions:                                                              *;
;*                                                                          *;
;*     _GetClkTicks()                                                       *;
;*                                                                          *;
;****************************************************************************;
	.286
	.MODEL MEDIUM, C
	.DATA
control	dw	?
status	dw	?
	.CODE
;****************************************************************************;
GetClkTicks	PROC FAR USES BX CX DX, 
	pushf			; save flag register
	cli                     ; clear interrupts
;
; Setup a countdown timer.
;
	mov	al, 0bch	; rw lsb then msb, mode2
	out	43h, al		; command to counter
	mov	al, 0FFh
	out	42h, al		; load lsb of counter
	out	42h, al		; load msb of counter
	mov	cx, 00080h	; set up cpu loop
	mov	bx, 0FFh 
 	in	al, 61h		; read status byte of 82C301
	or	al, 1		; set lsb to 1
	out	61h, al		; enables the counter to start decrementing
;
; Timing Loop
;
	mov	ax, 0FFFFh
	ALIGN	4
;
;
block	MACRO
	idiv	bl		; 17 cycles
	imul	bl		; 13 cycles
	mov	ax, 0FFFFh	;  2 cycles
	ENDM
;
;
l1:
	REPT	(2048/32)       ; repeat this many times
	block			; 32 machine cycles per "BLOCK"
	ENDM

	dec	cx		;  1 machine cycle
	jcxz	done		;  5 machine cycles
	jmp	l1		;  3 machine cycles
   				; 1 loop is 2057 CPU clocks
done:
;
; End Timing Loop
;
	mov	al, 0d8h
	out	43h, al		; halts the counter
        push	ax
	pop	ax
	in	al, 42h		; read counter lsb 
	mov	ah, al
	in	al, 42h		; read counter msb
	mov	bl, al
	mov	al, ah
	mov	ah, bl
	popf
	ret
GetClkTicks	ENDP
;****************************************************************************
	END
------8<------------------------ CUT HERE ----8<-----------------------------

And now comes the MS C code, which basically performs interpretation of the
data returned from the assembly. Not clean, and not guaranteed to be 100%
accurate, but by screwing with the fudge factor, you should be able to get
it close enough.... Hint, Right now, on the 20 machines I tried it on, only
one 286 didn't read true, and it only read high by a 1 Mhz.

------8<------------------------ CUT HERE ----8<-----------------------------
#define FUDGE_286  1.3178
#define FUDGE_386  1.3424
#define FUDGE_486  1.52
#define FUDGE_486C 1.19

#define FUDGE      1.315

main()
{
  unsigned long cycles, ticks;
  float mhz;
  unsigned x;
  
  x = GetClkTicks();
  cycles = (long) 2057 * 0x0080;
  ticks  = 0xFFFF - x;
  mhz = (FUDGE * cycles) / ticks;
  
  printf( "Clock = %u, [%4x]\n",x,x );
  printf( "cycles= %lu\n",cycles );
  printf( "ticks = %lu\n",ticks);
  printf( "MHz   =%8.5f\n",mhz );
 
}
------8<------------------------ CUT HERE ----8<-----------------------------
And now, for the rest of the story:

The fudge factor is determined by taking the known clock rate, and running,
making changes until the numbers ring true.  This we did on about 20 machines,
so the fudge factor should be 95% good to go.

Anyhow, if you need to know more, or are p*ssed because I posted C code,
email to me.  (Haven't spoken pascal in about 4 years, and figured that if
you need it bad enough you'd convert it to pascal).

So, Good Luck, and let me know how it goes.
_______________________________________________________________________________
Ed Felton           | When you wish to produce a result by means of an 
felton@eng3.sci.com | instrument, do not allow yourself to complicate it
                    |                           -- Leonardo da Vinci 
        Disclaimer: Even if I had opinions, who would want them??? 

phys169@csc.canterbury.ac.nz (12/07/90)

In article <699@eng3.UUCP>, felton@eng3.UUCP (Ed Felton) writes:
> Daniel S. Lewart writes:
>   Can anyone point me to or provide me with some code which will determine the
>   clock speed?
> And now comes the MS C code...

If anyone does want a Pascal+inline asm program to do it (and a bit more), let
me know. Mine works on old 8088's, V20's, 286's, 8086's, and 80386(s/d)X.

Mark Aitchison, Physics, University of Canterbury, New Zealand.