⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.pas

📁 dos下检测pci设备列表的PASCAL代码
💻 PAS
字号:
Program PCI;

{$G+}
{$R-}
{$S-}
{$I+}
{$N+}
{$E+}
{$Q-}



uses newdelay,dos,crt;


{$I classes.pas}


{
This code is Written by Craig Hart in 1996-2005. It is released as freeware;
please use and modify at will. No guarantees are made or implied.


Please read the accompaning documentation PCI.DOC for all the info
relating to this program!
}



const
revision: string[5]='1.1';

type treedata =
record
b,
d,
f: byte;
vid,
did: word;
end;

var
olb,
lastd,
lastb,
agpbusnum,
lw,
wrlncount,
PCIverhi,
PCIverlo,
PCIchar,
PCI_hibus,
errcode,
deviceid,
func,
info,
lb,
bus,
sum,
disp,
cap_ptr,
max: byte;

showtree,
pdatareg,
found,
businfo,
userev,
tableok,
dorouting,
dopcirouting,
summary,
bogusid,
genssid,
dumpregs,
usebios,
failed,
first,
installermode: boolean;


irqmap: array[0..15] of byte;

pdata: array[0..15] of byte;
pscale: array[0..15] of byte;
presult: array[0..15] of byte;


tree: array[0..199] of treedata;

pmcsr,
romsize,
romresult,
rom_backup: longint;

spl: real;

count,
mb,
ml,
conmap,
len,
addr,
index,
i,
j,
l,
v: word;

f: text;

revchk,
oemidnum,
oemidstr,
cmdstr,
vstr,
cmpstr: string;


infotbl: array[0..$ff] of byte;

irqbuff: array[0..1023] of byte;

linecounter   : word;
org_output: pointer;


cardbus: array[1..16] of byte;
cbu,
cardptr: byte;


















procedure pagefilter1(var t:text);assembler;
asm
push ax
push di
push es
push cx

les di,[t]
mov cx,es:[di+TextRec.BufPos]
les di,es:[di+TextRec.BufPtr]
cld
mov al,10

@sl:
jcxz @ret
dec cx
scasb
jne @sl
inc linecounter
jmp @sl

@ret:
pop cx
pop es
pop di
pop ax
end;

procedure pagefilter2;assembler;
asm
push ax
mov ax,WindMax
shr ax,8
cmp linecounter,ax
jb @ret

sub ax,ax
int $16

mov linecounter,0

@ret:
pop ax
end;

procedure page_output_FlushFunc;assembler;
asm
push es
push bx
call pagefilter1
push es
push bx
call [org_output]
call pagefilter2
retf 4
end;



function cvtb(b:byte) : byte;
begin
if b>9 then cvtb:=b+ord('A')-10 else cvtb:=b+ord('0');
end;

function wrhexb(byt:byte): string;
begin
wrhexb:=chr(cvtb(byt and $0f));
end;

function wrhex(byt:byte) : string;
begin
wrhex:=chr(cvtb((byt and $f0) shr 4))+chr(cvtb(byt and $0f));
end;

function wrhexw(wor:word): string;
begin
wrhexw:=chr(cvtb(wor shr 12))+chr(cvtb((wor shr 8) and $f))+chr(cvtb((wor shr 4) and $f))+chr(cvtb(wor and $f));
end;


(* Make the PCI configuration status register printout pretty *)
(* Input = the string to be output *)

function IORedirected : boolean ; Assembler;
asm
push ds
mov ax,prefixseg
mov ds,ax
xor bx,bx
les bx,[bx + $34]
mov al,es:[bx]
mov ah,es:[bx +1]
pop ds
cmp al,ah
mov al,true
jne @exit

mov al,false

@exit:
end;

function lookup_bios(deviceid,func,bus:byte;index:word) : byte;

var inf:byte;

begin
asm
mov ax,$b108
mov bl,deviceid
shl bl,3
add bl,func
mov bh,bus
mov di,index
int $1a
jc @exit

mov failed,false
mov inf,cl
@exit:
mov errcode,ah
end;
lookup_bios:=inf;
end;


function lookup_hw(deviceid,func,bus:byte;index:word) : byte;
var inf:byte;

begin
asm
mov ax,$8000
mov al,bus
db $66;shl ax,16

mov ax,index
and ax,00fch
mov ah,deviceid
shl ah,3
add ah,func

mov dx,0cf8h
db $66;out dx,ax

mov ax,index
and ax,3
mov bl,8
mul bl
mov cx,ax

mov dx,0cfch
db $66;in ax,dx
db $66;shr ax,cl
mov inf,al
mov failed,false


db $66;xor ax,ax
mov dx,0cf8h
db $66;out dx,ax

end;
lookup_hw:=inf;
end;

procedure showinstallerinfo;
begin
if infotbl[$b]=1 then
begin
write('V:',wrhexw(infotbl[1] shl 8+infotbl[0]),' ');

write('D:',wrhexw(infotbl[3] shl 8+infotbl[2]),' ');

write('S:');
if infotbl[$e] and $7f=0 then
begin
write(wrhexw(infotbl[$2f] shl 8+infotbl[$2e]));
write(wrhexw(infotbl[$2d] shl 8+infotbl[$2c]),' ');
end else write('00000000 ');

write('B:',bus,' ');

write('E:');
if deviceid<10 then write('0');
write(deviceid,' ');

write('F:',func,' ');

write('I:');
if (infotbl[$3c]<16) and (infotbl[$3c]>0) then
begin
if infotbl[$3c]<10 then write('0');
write(infotbl[$3c],' ');
end else write('00 ');

write('N:');
if (infotbl[$3c]<16) and (infotbl[$3c]>0) then
begin
if infotbl[$3d]=0 then write('- ') else write(chr(infotbl[$3d]+64),' ');
end else write('- ');

write('C:');
write(wrhex(infotbl[$b]),' ');

write('U:');
write(wrhex(infotbl[$a]),' ');

write('P:');
write(wrhex(infotbl[$9]),' ');

write('R:');
write(wrhex(infotbl[$8]),' ');

writeln;
end;
end;

procedure showallinfo;
var
j,
i     : integer;
pp,
nn,
x: byte;
gotit: boolean;
begin
showinstallerinfo;
end;

begin
agpbusnum:=$ff;
businfo:=false;
dorouting:=true;
dopcirouting:=false;
dumpregs:=false;
usebios:=true;
summary:=false;
installermode:=false;
cardptr:=0;

{ the following hack permits MS-DOS display output redirection to work }
if ioredirected then
begin
writeln('Craig Hart''s PCI+AGP bus sniffer, version ',revision,', freeware made in 1996-2001.');
assign(output,'');
rewrite(output);
end else
{ code to do page pausing }
begin
ClrScr;
linecounter:=0;
with TextRec(Output) do
begin
org_output:=FlushFunc;
FlushFunc:=@page_output_FlushFunc;
end;
end;
for i:=0 to 15 do irqmap[i]:=0;
failed:=true;




if paramcount>0 then
begin
for i:=1 to paramcount do
begin
cmdstr:=paramstr(i);
for j:=1 to length(cmdstr) do cmdstr[j]:=upcase(cmdstr[j]);
if (cmdstr='/R') or (cmdstr='-R') then showtree:=true;
if (cmdstr='/H') or (cmdstr='-H') then usebios:=false;
if (cmdstr='/D') or (cmdstr='-D') then dumpregs:=true;
if (cmdstr='/T') or (cmdstr='-T') then dorouting:=false;
if (cmdstr='/P') or (cmdstr='-P') then dopcirouting:=true;
if (cmdstr='/B') or (cmdstr='-B') then businfo:=true;
if (cmdstr='/S') or (cmdstr='-S') then summary:=true;
if (cmdstr='/I') or (cmdstr='-I') then installermode:=true;
if (cmdstr='?') or (cmdstr='/?') or (cmdstr='-?') then
begin
textmode(co80);
writeln(' Help for PCI  (Version ',revision,')');
textcolor(8);
writeln('哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?);
textcolor(7);
writeln;
writeln('Usage: PCI [-H][-D][-S][-T][-B][-P][-R][-?]    [ ] indicates optional parameter');
writeln;
writeln('-H : Use direct hardware access (instead of the BIOS) to retrieve PCI Info');
writeln('     May be required for accurate reporting on Intel 430FX chipset+Award BIOS');
writeln('-D : Do a hex-dump of each device''s entire configuration space');
writeln('-S : Create a brief, summary report only; only devices and IRQs listed');
writeln('-T : Disable the test ROM IRQ Routing Table function');
writeln('-B : Enable display of the Bus, Device & Function information');
writeln('-P : Enable display of PCI slot routing data');
writeln('-I : Installer mode: produce raw data dump (for use with auto-setup programs)');
writeln('-R : Draw a Tree of Busses, Devices and Device Functions');
writeln('-? : Displays this help screen!');
writeln;
writeln('PCI Supports generating reports to a file or printer using MS-DOS pipes; i.e.');
writeln;
writeln('  PCI -D > REPORT.TXT  (Save report to file),  PCI > LPT1:  (Print report)');
writeln;
writeln('PCI is written by Craig Hart, and is released as freeware, with no restictions');
write('on use or copying. Visit ');
textcolor(11);
write('http://members.datafast.net.au/dft0802 ');
textcolor(7);
writeln('for updates to');
writeln('the program and the PCI Database file PCIDEVS.TXT');
halt(10);
end;
end;
end;


{ fix up conflicting commandline switches }

if installermode then
begin
dorouting:=false;
dopcirouting:=false;
dumpregs:=false;
businfo:=false;
summary:=false;
end;
{
if summary then
begin
dumpregs:=false;
dopcirouting:=false;
dorouting:=false;
end;
}
if test8086<2 then
begin
writeln('PCI Halted:');
writeln;
writeln('The PC Must be at least a 386 to possibly have a PCI or AGP bus!');
halt(1);
end;

{ Look for PCI BIOS }

asm
mov ax,$b101
int $1a
jc @exit

{ check signature bytes OK }
cmp dx,$4350
jne @exit

{ check no error code returned > AH=00=Success }
cmp ah,0
jne @exit

mov PCIchar,al
mov PCI_hibus,cl
mov PCIverlo,bl
mov PCIverhi,bh
mov failed,false

@exit:
end;

if failed then
begin
writeln('PCI Halted:');
writeln;
writeln('No PCI BIOS was detected! (NB: I don''t work under Windows NT/2000/XP/2003 etc!)');
writeln;
writeln('For PCI reports under Win NT-era OS''s such as NT/2K/XP/2K3, use PCI32.EXE');
writeln('which is available from the same website as this program (See PCI /? for the');
writeln('website address.)');
writeln;
halt(2);
end;



{ OK, we have PCI... do our stuff.. }


begin
for bus:=0 to pci_hibus do{ fix bugs for 440LX chipset, 2 PCI buses, AGP=1 bus! }
begin
for deviceid:=0 to $1f do
begin
func:=0;
repeat
index:=0;
repeat
if usebios then info:=lookup_bios(deviceid,func,bus,index) else info:=lookup_hw(deviceid,func,bus,index);
infotbl[index]:=info;
inc(index);
{don't try to read cfg-space of non-existant devices: hangs some chipsets!}
if index=2 then if (infotbl[0]=$ff) and (infotbl[1]=$ff) then index:=$100;
{don't read past $3f if in short-info modes; avoids crashing on intolerant hardware!}
if index=$40 then if installermode or summary then index:=$100;
until (index=$100);
if (infotbl[0]<>$ff) or (infotbl[1]<>$ff) then
begin
{ remember CardBus stuff for later; skip if far bus=0 (i.e. unconfigured) }
if (infotbl[$e] and $7f=2) and (infotbl[$19]<>0) then
begin
cardbus[cardptr+1]:=infotbl[$19];
cardptr:=cardptr+1;
end;
showallinfo;
end;
inc(func);
{ if func 0 = invalid device, don't test for presence of func 1->7 at all. [$e] isn't valid if [0] and [1] aren't!! }
if (func=1) and (infotbl[0]=$ff) and (infotbl[1]=$ff) then func:=8;
{ If not multi-device device, then don't test for func 1-7 as some cards
incorrectly answer back on all 8 function numbers!!! S3 trio64, for example - stupid!  }
if (func=1) and (infotbl[$e] and $80=0) then func:=8;
until func=8; {func }
end; {dev }
end; { bus }



{ now scan any CardBus busses that weren't included in the BIOS bus count }



if cardptr>0 then
begin
for cbu:=1 to cardptr do{ scan all cardbus busses }
begin
bus:=cardbus[cbu];
if bus>pci_hibus then{ but only those the BIOS hasn't already had us scan }
begin
for deviceid:=0 to $1f do
begin
func:=0;
repeat
index:=0;
repeat
if usebios then info:=lookup_bios(deviceid,func,bus,index) else info:=lookup_hw(deviceid,func,bus,index);
infotbl[index]:=info;
inc(index);
if index=2 then if (infotbl[0]=$ff) and (infotbl[1]=$ff) then index:=$100;
if index=$40 then if installermode or summary then index:=$100;
until (index=$100);
if (infotbl[0]<>$ff) or (infotbl[1]<>$ff) then showallinfo;
inc(func);
if (func=1) and (infotbl[0]=$ff) and (infotbl[1]=$ff) then func:=8;
if (func=1) and (infotbl[$e] and $80=0) then func:=8;
until func=8;
end;
end;
end;
end;
end;
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -