Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MHz ?

8 views
Skip to first unread message

Steven Smyth

unread,
Nov 9, 1996, 3:00:00 AM11/9/96
to

Hi Leute !

Ich wuerd' mal gerne wissen, wie man die MHz-Zahl des Rechners
herausbekommt !!

Geht das unter Pascal ?
Wenn ja, dann wie ?

Steven Smyth (SPS)

+-------------------------
|+===== +====+ +=====
|| | | |
|+====+ |====+ +====+
| | | |
|=====+ | =====+
|-----------+
| +------------


# Origin: (55:500/1900.138)

Ingo Boettcher

unread,
Nov 11, 1996, 3:00:00 AM11/11/96
to

Moin Steven!

Steven Smyth%55:500/1900.138@2:240/2166.99 konnte sich am 09.11.96 nicht
verkneifen,
etwas zum Thema "MHz ?" zu schreiben:

SS> Ich wuerd' mal gerne wissen, wie man die MHz-Zahl des Rechners
SS> herausbekommt !!

Tja...

SS> Geht das unter Pascal ?

Latuernich!

SS> Wenn ja, dann wie ?

Erstmal etwas Theorie (wichtig!):

Jeder Assembler-Befehl braucht auf jedem Prozessor eine bestimmte Anzahl an
Takten zur Ausfuehrung. Fuer eine Taktfrequenzmessung nimmt man nun einen
Befehl zur Hand, der relativ lange zur Ausfuehrung braucht, damit die
Messung einfacher wird. In den meisten Routinen wird der Befehl AAM
verwendet, der recht "lahm" ist. Es werden nun einige Tausend dieser Befehle
in den Speicher geschrieben und ausgefuehrt, wobei die Ausfuehrungszeit
gemessen wird. Aus den ermittelten Werten kann man nun recht genau die
Taktfrequenz berechnen.
Unbedingt noetig ist dafuer aber die relativ genaue Erkennung des
Prozessors, da die Befehle auf fast jedem Prozessor unterschiedlich lange
brauchen.

Die folgende Unit dient hauptsaechlich zur CPU-Erkennung, bietet aber auch
eine Routine zur Taktfrequenzerkennung. Wenn irgendwas nicht klar ist,
schick mir nochmal ne Mail. Sorry wegen der gefaehrlichen Groesse... :(

{ Unit : CPUDET.PAS V1.61
Funktion : Ermittlung des Prozessors
Sprache : Turbo Pascal ab 6.0
Autor : Ingo Boettcher
Datum : 23.10.1996
Copyright (c) 1994-96 IB-Soft

Diese Unit stellt eine Prozedur zur Erkennung des verwendeten
Prozessors und seiner Taktfrequenz dar. Erkannt werden diverse heute
bekannte Intel-kompatible Prozessoren.

Diese Unit ist Freeware und darf beliebig weiter verwendet werden.
Wenn Sie diese Unit in einem Ihrer Programme verwenden, sollte aber
wenigstens im Programm oder in der Dokumentation ein kleiner Hinweis
auf das Originalcopyright verbleiben. Kleine Spenden nehme ich
natuerlich auch gerne.

Die Unit basiert z.T. auf Veroeffentlichungen der Zeitschrift c't,
auf Daten gesammelt von Christian Ludloff und auf einigen Tips von
Michael E. Holin (PC-Config). Bei der NexGen Erkennung konnte ich
auf einige Hilfe von Thomas Moenkemeier zurueckgreifen. Die Cyrix-
Erkennung wurde von Christian Klak korrigiert, die CPU-Reset Teile
stammen aus Info+ und von Eike Frost. Danke an dieser Stelle allen
Helfern!

[...]

I B - S O F T Tel: 04221-20858
Ingo Boettcher Fido: 2:2426/3110.59
Borkumer Str. 10 Email: in...@fate.ohz.north.de
27755 Delmenhorst

}

Unit CPUDet;
{$X+}

Interface

Const
CPUIDOk: Boolean = False; { wurde CPUID-Test schon durchgefuehrt? }

Var
idFamily, idModel, idStepping: Word;
idFeatures: LongInt;
idCopyright: String; { Info-Variablen, nach Aufruf von GetPrzTyp gesetzt }

Function GetPrzTyp: String; { liefert Prozessortyp als String zurueck }
Function GetCPUSpeed: Word; { berechnet Taktfrequenz; 6666 = 66,66 MHz }
Function GetProc: Byte; { ganz einfache Methode, liefert nur bis 486 }

Implementation

Uses Dos;

Const
Unknown: Boolean=False;

Var
EAX, EBX, EDX, ECX: LongInt;
Delta: Byte;
Alt06: Pointer;
ExitSave: Pointer;
ProzessorTyp: String;
AAMTime: LongInt;

Function Byte2Str(Wert: Byte): String;
Var
Zwischen: String;
Begin
Str(Wert, Zwischen);
Byte2Str:=Zwischen;
End;

Function GetProc: Byte;
Begin
Asm
PUSHF
PUSH CX
PUSH DX
PUSH DI
PUSH SI
PUSH ES
XOR AX,AX
PUSH AX
POPF
PUSHF
POP AX
AND AX,0F000h
CMP AX,0F000h
JZ @kleiner286

MOV DL,006h
MOV AX,07000h
PUSH AX
POPF
PUSHF
POP AX
AND AX,07000h
JZ @pende

INC DL

CLI
DB 066h,08bh,0dch
DB 066h,083h,0e4h,0fch
DB 066h,09ch
DB 066h,058h
DB 066h,08bh,0c8h
DB 066h,035h,000h,0h,4h,0h
DB 066h,050h
DB 066h,09dh
DB 066h,09ch
DB 066h,058h
DB 066h,051h
DB 066h,09dh
DB 066h,033h,0c1h
DB 066h,0c1h,0e8h,012h
DB 066h,083h,0e0h,001h
DB 066h,08bh,0e3h
STI
ADD DL,AL
JMP @pende

@kleiner286:
MOV DL,04
MOV AL,0FFh
MOV CL,021h
SHR AL,CL
JNZ @t88_86

MOV DL,02
STI
MOV SI,0000
MOV CX,0FFFFh
DB 0f3h,026h,0ach
OR CX,CX
JZ @t88_86
MOV DL,00
@t88_86:
PUSH CS
POP ES
STD
MOV AL,0FBh
MOV CX,0003
CALL @funk
@funk_ret:
CLI
REP STOSB
CLD
NOP
NOP
NOP
INC DX
NOP
STI
@pende:
MOV [BP-01],DL
POP ES
POP SI
POP DI
POP DX
POP CX
POPF
JMP @ende
NOP
@funk:
POP DI
ADD DI,0009
JMP @funk_ret
@ende:
End;
End;

Procedure Int06(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
Interrupt;
Begin
Inc(IP, Delta);
AX:=$82;
Unknown:=True;
End;

Function CPUIDSupport: Boolean;
Var
Dummy: Byte;
Begin
Dummy:=0;
Asm
db 66h, 9ch (* pushfd EFlags auf den Stack *)
db 66h, 58h (* pop eax nach EAX holen *)
db 66h, 8bh, 0c8h (* mov ecx,eax in ECX merken *)
db 66h, 35h, 00h, 00h, 20h, 00h (* xor eax,200000h Bit 21 umdrehen *)
db 66h, 50h (* push eax das Ganze auf den Stack
*)
db 66h, 9dh (* popfd ins EFLAG-Register
holen *)
db 66h, 9ch (* pushfd von da wieder auf den
Stack *)
db 66h, 58h (* pop eax und als EAX zurueck *)
db 66h, 33h, 0c1h (* xor eax,ecx Bit 21 testen *)
je @weiter
MOV Dummy,1
@weiter:
End;
CPUIDSupport:=(Dummy<>0);
End;

Function TestCPUID: Boolean;
Var
CrStr: Array [1..12] Of Char Absolute EBX;
Copyr: String;
CType, Model, Family, Stepping: Byte;
Features: LongInt;

Procedure CPUID;
Begin
Delta:=2;
Inline($66/$A1/EAX/
$0F/$A2/ { CPUID }
$66/$A3/EAX/ { MOV [EAX],EAX }
$66/$89/$1E/EBX/ { MOV [EBX],EBX }
$66/$89/$0E/ECX/ { MOV [ECX],ECX }
$66/$89/$16/EDX); { MOV [EDX],EDX }
End;

Begin
EAX:=0; CPUID;
TestCPUID:=Not Unknown;
If Unknown Then Exit;
Copyr:=CrStr;
EAX:=1; CPUID;
Model:=(EAX Shr 4) And $F;
Family:=(EAX Shr 8) And $F;
Stepping:=EAX And $F;
Features:=EDX;
CPUIDOk:=True;
idCopyright:=Copyr;
idModel:=Model;
idFamily:=Family;
idStepping:=Stepping;
idFeatures:=Features;
If Copyr='UMC UMC UMC ' Then
ProzessorTyp:='UMC '
Else If Copyr='CyrixInstead' Then
ProzessorTyp:='Cyrix '
Else If (Copyr='AuthenticAMD') Or (Copyr='AMD ISBETTER') Then
ProzessorTyp:='AMD '
Else If Copyr='GenuineIntel' Then
ProzessorTyp:='Intel '
Else If Copyr='NexGenDriven' Then
ProzessorTyp:='NexGen '
Else
ProzessorTyp:='';
Case Family Of
4: Begin
If ProzessorTyp='Intel ' Then
Begin
ProzessorTyp:=ProzessorTyp+'486';
AAMTime:=15;
Case Model Of
0,1: ProzessorTyp:=ProzessorTyp+'DX';
2: ProzessorTyp:=ProzessorTyp+'SX';
3: ProzessorTyp:=ProzessorTyp+'DX2';
4: ProzessorTyp:=ProzessorTyp+'SL';
5: ProzessorTyp:=ProzessorTyp+'SX2';
7: ProzessorTyp:=ProzessorTyp+'DX2 (WB)';
8: ProzessorTyp:=ProzessorTyp+'DX4';
9: ProzessorTyp:=ProzessorTyp+'DX4 (WB)';
Else ProzessorTyp:=ProzessorTyp+'unbekannt (Modell
'+Byte2Str(Model)+', Stepping '+Byte2Str(Stepping)+')';
End;
End
Else If ProzessorTyp='AMD ' Then
Begin
AAMTime:=15;
Case Model Of
3: ProzessorTyp:=ProzessorTyp+'486DX2';
7: ProzessorTyp:=ProzessorTyp+'486DX2 (WB)';
8: ProzessorTyp:=ProzessorTyp+'486DX4';
9: ProzessorTyp:=ProzessorTyp+'486DX4 (WB)';
$0E: ProzessorTyp:=ProzessorTyp+'5x86 (WT)';
$0F: ProzessorTyp:=ProzessorTyp+'5x86 (WB)';
Else
ProzessorTyp:=ProzessorTyp+'486 (Modell '+Byte2Str(Model)+',
Stepping '+Byte2Str(Stepping)+')';
End;
End
Else If ProzessorTyp='UMC ' Then
Begin
AAMTime:=12;
Case Model Of
1: ProzessorTyp:=ProzessorTyp+'U5SD';
2: ProzessorTyp:=ProzessorTyp+'U5S';
Else
ProzessorTyp:=ProzessorTyp+'Modell '+Byte2Str(Model)+', Stepping
'+Byte2Str(Stepping);
End;
End
Else If ProzessorTyp='Cyrix ' Then
Begin
AAMTime:=15;
Case Model Of
9: Begin ProzessorTyp:=ProzessorTyp+'Cx5x86'; AAMTime:=19; End;
$1F: ProzessorTyp:=ProzessorTyp+'Cx486DX4';
$2D: Begin ProzessorTyp:=ProzessorTyp+'Cx5x86'; AAMTime:=19; End;
$81: ProzessorTyp:='Texas Instruments TI486DX4';
Else
ProzessorTyp:=ProzessorTyp+'Modell '+Byte2Str(Model)+', Stepping
'+Byte2Str(Stepping);
End;
End
Else
Begin
ProzessorTyp:=ProzessorTyp+'486 (Modell '+Byte2Str(Model)+',
Stepping '+Byte2Str(Stepping)+')';
AAMTime:=15;
End;
End;
5: Begin
If ProzessorTyp='Intel ' Then
Begin
ProzessorTyp:='Pentium';
AAMTime:=18;
Case Model Of
0: ProzessorTyp:=ProzessorTyp+' 60/66 (A-Step)';
1: Begin
ProzessorTyp:=ProzessorTyp+' 60/66';
Case Stepping Of
3: ProzessorTyp:=ProzessorTyp+' (B1-Maske)';
5: ProzessorTyp:=ProzessorTyp+' (C1-Maske)';
7: ProzessorTyp:=ProzessorTyp+' (B1-Maske)';
End;
End;
2: Case Stepping Of
1: ProzessorTyp:=ProzessorTyp+' 75-100 (B1-Maske)';
2: ProzessorTyp:=ProzessorTyp+' 75-100 (B3-Maske)';
4: ProzessorTyp:=ProzessorTyp+' 75-120 (B5-Maske)';
5: ProzessorTyp:=ProzessorTyp+' 75-133 (C2-Maske)';
11: ProzessorTyp:=ProzessorTyp+' 120-133';
12: ProzessorTyp:=ProzessorTyp+' >=133 (cC0-Maske)';
Else ProzessorTyp:=ProzessorTyp+' >=75';
End;
3: Case Stepping Of
1: ProzessorTyp:=ProzessorTyp+' Overdrive 63';
2: ProzessorTyp:=ProzessorTyp+' Overdrive 83';
End;
4: ProzessorTyp:=ProzessorTyp+' Overdrive (P54T)';
5: ProzessorTyp:=ProzessorTyp+' Overdrive fuer DX4';
6: ProzessorTyp:=ProzessorTyp+' Overdrive (P5T)';
Else ProzessorTyp:=Prozessortyp+' unbekannt (Modell
'+Byte2Str(Model)+', Stepping '+Byte2Str(Stepping)+')';
End;
End
Else If ProzessorTyp='AMD ' Then
Begin
ProzessorTyp:=ProzessorTyp+'5k86';
AAMTime:=18; { ??? }
Case Model Of
0: ProzessorTyp:=ProzessorTyp+' P75';
Else ProzessorTyp:=Prozessortyp+' unbekannt (Modell
'+Byte2Str(Model)+', Stepping '+Byte2Str(Stepping)+')';
End;
End
Else If ProzessorTyp='NexGen ' Then
Begin
ProzessorTyp:=ProzessorTyp+'Nx586';
AAMTime:=18; { ??? }
Case Model Of
0: If Stepping=4 Then
ProzessorTyp:=ProzessorTyp+' 100'
Else If Stepping=6 Then
ProzessorTyp:=ProzessorTyp+' 120'
Else
ProzessorTyp:=ProzessorTyp+' unbekannt (Stepping
'+Byte2Str(Stepping)+')';
Else ProzessorTyp:=ProzessorTyp+' unbekannt (Modell
'+Byte2Str(Model)+')';
End;
End
Else If ProzessorTyp='Cyrix ' Then
Begin
AAMTime:=13;
Case Model Of
2,3: ProzessorTyp:=ProzessorTyp+'Cx6x86';
Else ProzessorTyp:=ProzessorTyp+'unbekannt';
End
End
Else
ProzessorTyp:=ProzessorTyp+'unbekannt';
End;
6: Begin
If ProzessorTyp='Intel ' Then
Begin
ProzessorTyp:='Pentium Pro';
AAMTime:=18; { ??? }
Case Model Of
0: ProzessorTyp:=ProzessorTyp+' (A-Step)';
1: Case Stepping Of
0: ProzessorTyp:=ProzessorTyp+' 133';
1: ProzessorTyp:=ProzessorTyp+' 150 (B0-Maske)';
2: ProzessorTyp:=ProzessorTyp+' 150 (C0-Maske)';
6: ProzessorTyp:=ProzessorTyp+' 166-200';
Else ProzessorTyp:=ProzessorTyp+' (unbekannt)';
End;
4: ProzessorTyp:=ProzessorTyp+' Overdrive (P55CT)';
Else
ProzessorTyp:=ProzessorTyp+'unbekannt';
End;
End
Else
ProzessorTyp:=ProzessorTyp+'unbekannt';
End;
Else
ProzessorTyp:=ProzessorTyp+' unbekannt (Modell '+Byte2Str(Model)+',
Stepping '+Byte2Str(Stepping)+')';
End;
End;

Function IsNexGen: Boolean; Assembler;
Asm
MOV AX,$5555
XOR DX,DX
MOV CX,2h
DIV CX
JZ @IsNexGen
XOR AX,AX
@IsNexGen:
End;

Function CyrixOrTI: Boolean;
Var
Is_Cyrix: Boolean;
Begin
{ Abfrage auf 486 oder hoeher -> wegen den dummen Nexgens ;) }
If GetProc < 8 Then
CyrixOrTI := False
Else
Begin
Asm
mov ax,5555h
xor dx,dx
mov cx,2h
clc
div cx
jc @No_Cyrix
mov Is_Cyrix,1
jmp @Ende
@No_Cyrix:
mov Is_Cyrix,0
@Ende:
End;
CyrixOrTI := Is_Cyrix;
End;
End;

Procedure WriteCyrix;
Var
Dir0, Dir1: Byte;
Begin
AAMTime:=17;
Port[$22]:=$FE; Dir0:=Port[$23];
Port[$22]:=$FF; Dir1:=Port[$23];
Case Dir0 Of
$00: ProzessorTyp:='Cyrix Cx486SLC';
$01: ProzessorTyp:='Cyrix Cx486DLC';
$02: ProzessorTyp:='Cyrix Cx486SLC2';
$03: ProzessorTyp:='Cyrix Cx486DLC2';
$04: ProzessorTyp:='Cyrix Cx486SRx';
$05: ProzessorTyp:='Cyrix Cx486DRx';
$06: ProzessorTyp:='Cyrix Cx486SRx2';
$07: ProzessorTyp:='Cyrix Cx486DRx2';
$08: ProzessorTyp:='Cyrix Cx486SRu';
$09: ProzessorTyp:='Cyrix Cx486DRu';
$0A: ProzessorTyp:='Cyrix Cx486SRu2';
$0B: ProzessorTyp:='Cyrix Cx486DRu2';
$10: ProzessorTyp:='Cyrix Cx486S';
$11: ProzessorTyp:='Cyrix Cx486S2';
$12: ProzessorTyp:='Cyrix Cx486Se';
$13: ProzessorTyp:='Cyrix Cx486S2e';
$1A: Begin ProzessorTyp:='Cyrix Cx486DX'; AAMTime:=16; End;
$1B: ProzessorTyp:='Cyrix Cx486DX2';
$28: ProzessorTyp:='Cyrix 5x86-S (1x Clock-Mode)';
$2A: ProzessorTyp:='Cyrix 5x86-P (1x Clock-Mode)';
$29: ProzessorTyp:='Cyrix 5x86-S (2x Clock-Mode)';
$2B: ProzessorTyp:='Cyrix 5x86-P (2x Clock-Mode)';
$2D: ProzessorTyp:='Cyrix 5x86-S (3x Clock-Mode)';
$2F: ProzessorTyp:='Cyrix 5x86-P (3x Clock-Mode)';
$2C: ProzessorTyp:='Cyrix 5x86-S (4x Clock-Mode)';
$2E: ProzessorTyp:='Cyrix 5x86-P (4x Clock-Mode)';
$30: ProzessorTyp:='Cyrix 6x86-S (1x Clock-Mode)';
$32: ProzessorTyp:='Cyrix 6x86-P (1x Clock-Mode)';
$31: ProzessorTyp:='Cyrix 6x86-S (2x Clock-Mode)';
$33: ProzessorTyp:='Cyrix 6x86-P (2x Clock-Mode)';
$35: ProzessorTyp:='Cyrix 6x86-S (3x Clock-Mode)';
$37: ProzessorTyp:='Cyrix 6x86-P (3x Clock-Mode)';
$34: ProzessorTyp:='Cyrix 6x86-S (4x Clock-Mode)';
$36: ProzessorTyp:='Cyrix 6x86-P (4x Clock-Mode)';
$FF: Begin ProzessorTyp:='Cyrix Cx486SLC/DLC/S?'; AAMTime:=16; End;
Else ProzessorTyp:='Cyrix Cx486?';
End;
ProzessorTyp:=ProzessorTyp+', Revision '+Byte2Str(Lo(Dir1))+', Stepping
'+Byte2Str(Hi(Dir1));
End;

Function GetPrzTyp: String;
Begin
ProzessorTyp:='unbekannt';
AAMTime:=0;
If GetProc=0 Then
Begin
ProzessorTyp:='8088';
AAMTime:=77;
End
Else If GetProc=1 Then
Begin
ProzessorTyp:='8086';
AAMTime:=77;
End
Else If GetProc=2 Then
Begin
ProzessorTyp:='NEC V20';
AAMTime:=15;
End
Else If GetProc=3 Then
Begin
ProzessorTyp:='NEC V30';
AAMTime:=15;
End
Else If GetProc=4 Then
Begin
ProzessorTyp:='80188';
AAMTime:=99;
End
Else If GetProc=5 Then
Begin
ProzessorTyp:='80186';
AAMTime:=99;
End
Else If GetProc=6 Then
Begin
ProzessorTyp:='80286';
AAMTime:=16;
End
Else
Begin
If CPUIDSupport Then
Begin
GetIntVec($06, Alt06);
SetIntVec($06, @Int06);
TestCPUID;
SetIntVec($06,Alt06);
End;
If ProzessorTyp='unbekannt' Then
Begin
If CyrixOrTI Then
WriteCyrix
Else If IsNexGen Then
Begin
ProzessorTyp:='NexGen (aelteres Modell)';
AAMTime:=18;
End;
End;
If ProzessorTyp='unbekannt' Then
Begin
If GetProc=7 Then
Begin
ProzessorTyp:='80386';
AAMTime:=17;
End
Else If GetProc=8 Then
Begin
ProzessorTyp:='80486DX';
AAMTime:=15;
End
Else If GetProc=9 Then
Begin
ProzessorTyp:='80486SX';
AAMTime:=15;
End
Else
Begin
ProzessorTyp:='>486';
AAMTime:=15; (* sagen wir jetzt einfach <g> *)
End;
End;
End;
GetPrzTyp:=ProzessorTyp;
End;

Function GetCpuSpeed: Word;
Const
Zykl = 838; {ns/Zyklus}
Type
BuffArray = Array [0..8100] Of Byte;
Var
Buffer: ^BuffArray;
PuffSeg, PUffOfs, NullWert, i: Word;
z1,Takt: Longint;
OldI: Pointer;

Procedure StartTimer; Assembler;
{ Setzt Timer auf 65536 dieser wird nun alle 838ns um eins verringert}
Asm
CLI
MOV AL,34h; OUT 43h,AL
XOR AL,AL ; OUT 40h,AL
OUT 40h,AL
STI
INT 88h
End;

Function ReadTimer: Word;
Begin
Asm
XOR AL,AL
OUT 43h,AL
End;
ReadTimer := 65535 - Port[$40] Shl 8 - Port[$40];
Asm
STI
End;
End;

Begin
If MaxAvail < 8200 Then
GetCPUSpeed := 0
Else
Begin
ProzessorTyp:=GetPrzTyp; { Initialisierung, damit AAM Zeit bekannt ist }
New(Buffer);
PuffSeg := Seg(Buffer^);
PuffOfs := Ofs(Buffer^);
GetIntVec($88,OldI);
SetIntVec($88,Buffer); { Interrupt auf Puffer umbiegen }
Mem[PuffSeg:PuffOfs] := $CF; { $CF = IRET }
StartTimer;
NullWert := ReadTimer; { Zeit fuer IRET messen }
For i := 0 To 3999 Do
MemW[PuffSeg:PuffOfs + i shl 1] := $AD4; { Puffer mit $D40A fuellen }
Mem [PuffSeg:PuffOfs + i shl 1 + 2] := $CF; { IRET ans Ende }
StartTimer;
Z1 := ReadTimer - NullWert; { reine Laufzeit bestimmen }
Takt := AAMtime * 100000 DIV (z1 * Zykl DIV 4000); { Takt * 100 }
If Takt Mod 100 = 98 Then Inc(Takt); { ggf. etwas runden }
If Takt Mod 100 = 99 Then Inc(takt); { ggf. etwas runden }
SetIntVec($88,OldI); { alten Interrupt wieder herstellen }
Dispose(Buffer);
GetCpuSpeed := Takt;
End;
End;

End.

Und tschuess Wie kann man die Welt aendern wollen,
Ingo wenn man sich selbst nichtmal aendern kann?

Sebastian Annies

unread,
Nov 12, 1996, 3:00:00 AM11/12/96
to

Steven Smyth%55:500/1900.138@2:240/2166.99 meinte am 09.11.96
zum Thema "MHz ?":

> Hi Leute !


>
> Ich wuerd' mal gerne wissen, wie man die MHz-Zahl des Rechners

> herausbekommt !!


>
> Geht das unter Pascal ?

> Wenn ja, dann wie ?
>

Also fangen wir an:

1. Prozessor ertesten
a 8088 Kommando geben
- korrekt ausgefuehrt, nicht kleiner als 8088
b 8086 Kommando geben
- korrekt ausgefuehrt, nicht kleiner als 8086
c 80186

d 80286

e 80386

f 80486

g Pentium

h PPro

2. Geschwindigkeit ertesten
a Ausfuehrungsgeschwindigkeit von verschiedenen Kommandos testen

b In einer Tabelle nachschauen welcher Prozessor eine aehnliche
Performance zeigt, der ist es dann !

Wie herausfindet ob es ein AMD Cyrix IBM Intel etc ist weiss ich nicht !
Alles in allem ist das aber mehr ASM als Pascal also etwas OT ...

Ciao
Sebastian
--

Axel Heider

unread,
Nov 12, 1996, 3:00:00 AM11/12/96
to

Hi Steven,
[official rubbish deleted - or is it necessary in a mail to you?]

SS> Ich wuerd' mal gerne wissen, wie man die MHz-Zahl des Rechners
SS> herausbekommt !!

------------------------------------------------------------------

{$g+}
function GetCPU: byte; {1=86,2=286,3=386,4=486,5=586,etc.} assembler;
asm
mov ax,1
pushf
pop bx
and bh, 0Fh
push bx
popf
pushf
pop cx
and ch,0F0h
cmp ch,0F0h
jz @bye
inc ax
or bh,0F0h
push bx
popf
pushf
pop cx
and ch, 0F0h
jz @bye
db 040h {inc ax}
db 066h, 08Bh,0DCh;
db 066h, 081h,0E4h,0FCh,0FFh,000h,000h
db 066h, 09Ch
db 066h, 05Ah
db 066h, 08Bh, 0CAh
db 066h, 081h, 0F2h, 000h, 000h, 004h, 000h
db 066h, 052h
db 066h, 09Dh
db 066h, 09Ch
db 066h, 05Ah
db 066h, 051h
db 066h, 09Dh
db 066h, 033h, 0D1h
db 066h, 081h, 0E2h, 000h, 000h, 004h, 000h
db 066h, 08Bh, 0E3h
je @bye
db 040h
db 066h, 09Ch
db 066h, 05Ah
db 066h, 08Bh, 0CAh
db 066h, 081h, 0F2h, 000h, 000h, 020h, 000h
db 066h, 052h
db 066h, 09Dh
db 066h, 09Ch
db 066h, 05Ah
db 066h ,051h
db 066h, 09Dh
db 066h, 033h, 0D1h, 074h, 00Eh
db 066h, 0B8h, 001h, 000h, 000h, 000h
db 00Fh, 0A2h
db 080h, 0E4h,00Fh, 0C1h, 0E8h, 008h
@bye:
end;

function GetCpuSpeed: word; { returns speed of cpu, 16 mhz = 1600 }
CONST zykl = 838; {ns/Zyklus}
count = 4000;

TYPE BuffArray = ARRAY[0..(Count shl 1) + 2] OF BYTE;

VAR BUFFER : ^BuffArray;
PuffSeg,PUffOfs: Word;
z1,Takt : Longint;
NullWert,i : WORD;
OldI : Pointer;
AAMTime : LongInt;

procedure StartTimer; assembler; {Setzt Timer auf 65536}
asm {dieser wird nun alle 838ns um eins verringert}
cli
mov al,34h; out 43h,al
xor al,al ; out 40h,al
out 40h,al
sti
int 88h
end;

function ReadTimer: word; assembler;
asm
cli
xor al,al
out 43h,al
mov bx,0ffffh
xor ah,ah
in al,40h
sub bx,ax
in al,40h
shl ax,8
sub bx,ax
mov ax,bx
sti
END;

BEGIN
IF MaxAvail < SizeOf(buffArray) then
BEGIN
GetCPUSpeed := 0;
Exit;
END ELSE
New(Buffer);

CASE GetCPU OF
1: AAMTime := 83; {086}
2: AAMTIME := 16; {286}
3: AAMTime := 17; {386}
4: AAMTime := 15; {486}
5: AAMTime := 18; {586}
end;

asm
mov ax,3588h
int 21h
mov word ptr Oldi + 2,es
mov word ptr Oldi + 0,bx

push ds
mov ax,2588h { Interrupt auf Puffer umbiegen }
lds dx,Buffer
int 21h
pop ds

les di,Buffer
mov PuffOfs,di
mov PuffSeg,es

mov byte ptr es:[di],$cf { $CF = IRET }
push bp; call StartTimer;
push bp; call ReadTimer; { Zeit fuer IRET messen }
mov Nullwert,ax
end;

fOR i := 0 to Pred(Count) shl 1 DO
MemW[PuffSeg:PuffOfs + i shl 1] := $0ad4; { Puffer mit AAM - $D40A fuellen }

asm
mov es,PuffSeg
mov di,PuffOfs
mov ax,i
add ax,ax
add ax,2
add di,ax
mov byte ptr es:[di],0cfh { IRET ans Ende }

push bp; call StartTimer { reine Laufzeit bestimmen }
push bp; call ReadTimer
sub ax,NullWert
mov word ptr z1 + 0,ax
mov word ptr z1 + 2,0h
end;

takt := AAMtime * 100000 DIV ((z1 * zykl) div (Count shl 1)); { Takt * 100 }
if takt mod 100 = 98 then inc(takt); { ggf. etwas runden }
if takt mod 100 = 99 then inc(takt); { ggf. etwas runden }

asm
push ds
mov ax,2588h
lds dx,Oldi
int 21h
pop ds

mov ax,word ptr takt + 0; mov @result+0,ax
mov ax,word ptr takt + 2; mov @result+2,dx
end; { alten Interrupt wieder herst.
}

Dispose(Buffer); { speicher freigeben }
end;
procedure Set8253Chip(count: Word);
(* The 8253 counter #0 is the heartbeat of the DOS clock. The BIOS loads
counter #0 with 0, mode 3. Some hi-res timing routines may leave it in
mode 2, which will affect these procedures. Use Set8253Chip(0) at the very
beginning of your program to load counter#0 the same way that the BIOS
does at power up. (Sloppy TSRs might still interfere.) *) assembler;
Asm
Mov CX, count (* count down from this *)
Cli (* do not disturb *)
Mov AL,36H (* counter 0, mode 3, RL=11 *)
OUT 43H,AL (* to 8253 control reg *)
Mov AL,CL
OUT 40h,AL (* write counter 0, LSB *)
Mov AL,CH
OUT 40h,AL (* write counter 0, MSB *)
STI (* enable interrupt *)
Mov ES,Seg0040 (* far data segment *)
Mov AX,ES:[6CH] (* get BIOS timer word *)
@wait:
CMP AX,ES:[6CH] (* wait for next tick *)
JE @wait (* to synchronize *)
end;

begin
Set8253Chip(0); {wichtig ! muss vor GetCpuSpeed aufgerufen werden, sonst
stimmen dir werte event. nicht}
Writeln('Takt: ',GetCpuSpeed/100:1:1,' Mhz');
end.

------------------------------------------------------------------

SS> Geht das unter Pascal ?
wie du sieht, geht das mit asm schneller.....und ich glaube nicht, dass
es in pascal wirklich geht...

SS> Wenn ja, dann wie ?
so wie oben :)

[official rubbish deleted, too]
cu soon,
Axel Heider

WICHTIG: Suche Soft-Bindung mit oder ohne Snowboard! (Raum Muenchen!)
HEI...@CUM.DE - THUNDER: 650:750/101.2 - ThunderNet? Apply! Ask 2:2480/404

christian muehlhaeuser

unread,
Nov 14, 1996, 3:00:00 AM11/14/96
to

hi Sebastian!

SA> Wie herausfindet ob es ein AMD Cyrix IBM Intel etc ist weiss ich nicht
SA> ! Alles in allem ist das aber mehr ASM als Pascal also etwas OT ...

take this:

=== Cut ===
var
Proc: byte;
Typ: String;

begin
asm
db 66h
xor ax, ax
inc ax
dw 41487
and ah, 0Fh
mov byte ptr proc, ah
xor ax, ax
dw 41487
db 66h
mov word ptr Typ[0], bx
db 66h
mov word ptr Typ[4], dx
db 66h
mov word ptr Typ[8], cx
end;
Move(Typ[0],Typ[1],SizeOf(Typ));
Typ[0]:=Chr(Pos(#0,Typ)-1);
WriteLn('Hersteller: ',Typ);
end. === Cut ===

cu,
chris [ch...@crazy.de]

0 new messages