home *** CD-ROM | disk | FTP | other *** search
- { WhichCPU - Yet another CPU-Identifier
- 1992,1993 by Michael Holin
- this is Public Domain
-
- Thanks to
-
- Michael Tischer and many others, for the base-cpu-id-routine
- Ted Forgeron & Pat Shea, for the base-npu-id-routine
- Hans-Ullrich Siehl, for his RapidCAD
- Roland Gorisch, for his Cyrix486
- c't Magazin, for many interesting articles
- PC-Professional Magazin for details on Pentium
- Andrew Rossmann, for his SYSID+
- (maybe soon comes a version, which
- detects 386sx and RapidCAD ;-)
- }
-
- {$F+,I-,R-,D-,S-,A+,V-}
- {$L wcpu.obj}
- uses dos,tpstring; {only used for byte to hex conversion}
- const ver:string[4]='0.50';
- var ret,ax,cpu,puffseg,puffofs,i,j,ccode,ncode:word;
- coproemu,weitek:boolean;
- regs:registers;
- p:pointer;
-
-
- function CoPro:word; external; {8087, 80287, 80387 ?}
- function GetProz:word; external; {gets prozessortyp}
-
- {works only on 80386+}
- function DXorSX:word; external; {Memory-Access with LODSD}
-
- procedure StartTimer; {Set Timer to 65536}
- begin {dec every 838ns by one}
- inline($FA/$B0/$34/$E6/$43/$EB/$00/$B0/$00/$E6/$40/$EB/$00/$E6/$40);
- end;
-
-
- function ReadTimer:word;
- begin
- port[$43]:=0;
- ReadTimer:=65535-port[$40] shl 8-port[$40];
- inline($FB);
- end;
-
- procedure MaskRev; {get CPU-Revision on new BIOSes}
- begin
- regs.ax:=$C910;
- intr($15,regs);
- if regs.ah=0 then begin
- write(' Rev.',hexb(regs.cl));
- end;
- end; {byte to hex from TPString-Unit}
-
-
- procedure info;
- begin
- if (paramstr(1)='cpu') or (paramstr(1)='CPU') then ret:=1;
- if (paramstr(1)='npu') or (paramstr(1)='NPU') then ret:=2;
- if paramstr(1)='?' then begin
- writeln(#10'for batchfiles use: WhichCPU cpu to return CPU-Code as errorlevel');
- writeln(' WhichCPU npu to return NPU-Code as errorlevel');
- writeln(#10'CPU : 88,86,V20,V30,188,186,286,386sx,-dx,RapidCAD,486sx,-dx,-slc,-dlc,Pentium');
- writeln('ERRL: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 , 14');
- writeln('NPU : none,software,87,287,387');
- writeln('ERRL: 0, 1, 2, 3, 4');
- writeln(#10'WhichCPU is an extract from the outstanding PC-Systeminfo-Benchmark-Program');
- writeln('PC-CONFIG (c) 1989,1993 by Michael Holin (available only in german language)');
- writeln('for further information write, call, fax, or mail to:');
- writeln(#10'Michael Holin Phone : +49 5323 3350');
- writeln('PO-Box 1146 Fax : +49 5323 3380');
- writeln('3392 Clausthal Fido : 2:241/3431');
- writeln('West-Germany Internet: himh@sun.rz.tu-clausthal.de');
- writeln(#10'all these numbers and addresses are valid until jun. 1993');
- halt;
- end;
- end;
-
-
- procedure TestCPU;
- var i,j,fa:word;
- z1,z2:longint;
- buszyklus:byte;
- begin
- case CPU of
- 0:begin
- write('8088');
- ccode:=0;
- end;
- 1:begin
- write('8086');
- ccode:=1;
- end;
- 2:begin
- write('NEC V20');
- ccode:=2;
- end;
- 3:begin
- write('NEC V30');
- ccode:=3;
- end;
- 4:begin
- write('80188');
- ccode:=4;
- end;
- 5:begin
- write('80186');
- ccode:=5;
- end;
- 6:begin
- write('80286');
- ccode:=6;
- end;
- 7:begin
- if true then begin
- mem[puffseg:Puffofs+0]:=$B9;
- mem[puffseg:Puffofs+1]:=$7F;
- mem[puffseg:Puffofs+2]:=$7F; {Loop cx slower than}
- mem[puffseg:Puffofs+3]:=$90; {dec cx+jne ? -> RapidCAD}
- mem[puffseg:Puffofs+4]:=$E2;
- mem[puffseg:Puffofs+5]:=$FE;
- mem[puffseg:Puffofs+6]:=$CF;
- starttimer;
- intr($88,regs); {start the loop}
- z1:=readtimer; {get time for doing that}
- mem[puffseg:Puffofs+0]:=$B9;
- mem[puffseg:Puffofs+1]:=$7F;
- mem[puffseg:Puffofs+2]:=$7F;
- mem[puffseg:Puffofs+3]:=$49;
- mem[puffseg:Puffofs+4]:=$75;
- mem[puffseg:Puffofs+5]:=$FD;
- mem[puffseg:Puffofs+6]:=$CF;
- starttimer;
- intr($88,regs);
- z2:=readtimer;
- if (z1*10) div (z2 div 10)>112 then begin {difference ?}
- write('RapidCAD');
- ccode:=9;
- cpu:=10;
- end
- else begin
- write('80386'); {distinguish between sx and dx}
- memw[$40:$f0]:=$2000; { $2000 DWords read at}
- memw[$40:$f2]:=1; {Offset 1}
- memw[$40:$f4]:=0; {Segment 0}
- i:=DXorSX;
- i:=DXorSX; {twice, to fetch from cache}
- memw[$40:$f2]:=2; {same at Offset 2}
- j:=DXorSX;
- if j+90<i then begin {difference ?}
- write('sx');
- ccode:=7;
- end
- else begin
- write('dx');
- ccode:=8;
- end;
- end;
- end else write('80386');
- Maskrev;
- end;
- 8:begin
- mem[puffseg:Puffofs+0]:=$B8;
- mem[puffseg:Puffofs+1]:=$AA;
- mem[puffseg:Puffofs+2]:=$AA;
- mem[puffseg:Puffofs+3]:=$BB;
- mem[puffseg:Puffofs+4]:=$55;
- mem[puffseg:Puffofs+5]:=$55;
- for i:=0 to 200 do memw[puffseg:Puffofs+6+i*2]:=$E3F7; {MUL}
- mem[puffseg:Puffofs+8+200*2]:=$CF;
- starttimer;
- intr($88,regs); {200 MULs}
- z1:=readtimer; {get time for doing that}
- mem[puffseg:Puffofs+0]:=$B8;
- mem[puffseg:Puffofs+1]:=$AA;
- mem[puffseg:Puffofs+2]:=$AA;
- mem[puffseg:Puffofs+3]:=$BB;
- mem[puffseg:Puffofs+4]:=$55;
- mem[puffseg:Puffofs+5]:=$55;
- for i:=0 to 200 do memw[puffseg:Puffofs+6+i*2]:=$0AD4; {AAM}
- mem[puffseg:Puffofs+8+200*2]:=$CF;
- starttimer;
- intr($88,regs); {200 AAMs}
- z2:=readtimer; {get time for doing that}
- if (longint(z1)*8)>(longint(z2)*5) then begin
- write('80486');
- if (copro>0) and not coproemu then begin
- write('dx'); {486 with real copro ?}
- ccode:=11;
- end
- else begin {without, or with 'soft'-copro}
- write('sx');
- ccode:=10;
- end;
- MaskRev;
- end
- else begin
- write('Cyrix 486');
- memw[$40:$f0]:=$2000; { $2000 DWords read at}
- memw[$40:$f2]:=1; {Offset 1}
- memw[$40:$f4]:=0; {Segment 0}
- i:=DXorSX;
- i:=DXorSX; {twice, to fetch from cache}
- memw[$40:$f2]:=2; {same at Offset 2}
- j:=DXorSX;
- if j+90<i then begin {difference ?}
- write('slc');
- ccode:=12;
- end
- else begin
- write('dlc');
- ccode:=13;
- end;
- end;
- end;
- 9:begin
- write('Pentium');
- ccode:=14;
- end;
- else write('???'); {shouldn't come to this point}
- end;
- writeln;
- end;
-
-
- function checkiit: boolean;
- var sw87,cw87: word;
- begin
- inline(
- $D9/$7E/<cw87/ { FSTCW cw87[BP] ; store control word }
- $DB/$E3/ { FINIT }
- $DB/$E8/ { FSBP0 ; set bank 0 }
- $D9/$EE/ { FLDZ ; load zero }
- $DB/$E3/ { FINIT }
- $DB/$EB/ { FSBP1 ; set bank 1 }
- $D9/$E8/ { FLD1 ; load 1 }
- $DB/$E8/ { FSBP0 ; set bank 0 }
- $D9/$E4/ { FTST ; test zero }
- $DD/$7E/<sw87/ { FSTSW sw87[BP] ; store status word }
- $DB/$E3/ { FINIT }
- $D9/$6E/<cw87); { FLDCW cw87[BP] ; load control word }
- checkiit:= (sw87 and $4100)=$4000;
- end;
-
-
- procedure testnpu;
- var z1,z2,z3:word;
- begin
- if (cpu=10) or (ccode=14) then begin {Rapidcad has it's own copro, but}
- write('build in'); {crashes in the copro-Routine ???}
- exit; {Maybe not a real 80387???}
- end;
- ax:=copro; {witch kind of copro}
- if (ccode=11) and (ax>0) and not coproemu then begin
- write('build in'); {486dx}
- exit;
- end;
- case ax of
- 0:begin
- write('none');
- ncode:=0;
- end;
- 1:begin
- write('8087');
- ncode:=2;
- end;
- 2:begin
- write('80287');
- ncode:=3;
- end;
- 3:begin
- write('80387');
- ncode:=4;
- end;
- end;
- if ax>1 then if checkiit then write(' (IIT)');
- if coproemu then begin
- write('-Emulation');
- ncode:=1;
- end;
- writeln;
- if ax=0 then exit;
- if paramstr(1)<>'debug' then exit;
-
- {the following code is for the future, to distinguish between}
- {some NPUs (IIT, Cyrix, AMD...)}
-
- mem[puffseg:Puffofs+0]:=$CF; {IRET}
- starttimer;
- intr($88,regs);
- z3:=readtimer;
- mem[puffseg:Puffofs+4]:=$CF;
- starttimer;
- intr($88,regs);
- z1:=readtimer;
- mem[puffseg:Puffofs+0]:=$DB; {FINIT}
- mem[puffseg:Puffofs+1]:=$E3;
- mem[puffseg:Puffofs+2]:=$D9; {FLDL2T}
- mem[puffseg:Puffofs+3]:=$E9;
- mem[puffseg:Puffofs+4]:=$D9; {4xFSQRT}
- mem[puffseg:Puffofs+5]:=$FA;
- mem[puffseg:Puffofs+6]:=$D9;
- mem[puffseg:Puffofs+7]:=$FA;
- mem[puffseg:Puffofs+8]:=$D9;
- mem[puffseg:Puffofs+9]:=$FA;
- mem[puffseg:Puffofs+10]:=$D9;
- mem[puffseg:Puffofs+11]:=$FA;
- mem[puffseg:Puffofs+12]:=$D9;
- mem[puffseg:Puffofs+13]:=$FA;
- mem[puffseg:Puffofs+14]:=$CF;
- starttimer;
- intr($88,regs);
- z2:=readtimer;
- writeln(z3,' ',z1,' ',z2);
- end;
-
-
- begin
- ret:=0;
- ccode:=0;
- ncode:=0;
- writeln(#10'WhichCPU V'+ver+' (c) by Michael Holin // Public Domain');
- writeln('WhichCPU ? for info');
- info;
- writeln(#10'Looking for: 8088,8086,V20,V30,80188,80186,80286,80386sx,-dx,RapidCAD');
- writeln( ' 80486sx,-dx,-slc,-dlc,Pentium');
- getmem(p,10000); {get Puffer}
- Puffseg:=seg(p^);
- PuffOfs:=ofs(p^);
- SetIntVec($88,ptr(PuffSeg,Puffofs)); {set Interrupt to Puffer}
- write('CPU found : ');
- ax:=getproz;
- coproemu:=ax and 32=32;
- cpu :=ax and 15;
- testcpu;
- write('NPU found : ');
- testnpu;
- case ret of
- 1:halt(ccode);
- 2:halt(ncode);
- end;
- end.
-