CODE: [Copy to clipboard]
;文件名:CHKPCI.ASM
;作者:netwinxp
;免责任声明:CHKPCI是个开放源码的自由软件,注意事项请参照http://www.gnu.org/licenses/
; 本人不对使用或修改该软件而可能导致的任何问题负责(即使事先被告知)。
;编译环境:masm6.11
;使用平台:DOS
.model tiny
.386
code segment
assume cs:code,ds:code,es:code
org 100H
START: mov ax,cs
mov ds,ax
mov es,ax
mov ax,0B101H;支持PCI 2.0?
int 1AH
jc PCIERR;否
cmp ah,0
jne PCIERR;否
cmp edx,' ICP'
jne PCIERR;否
;========读取PCI配置空间数据
mov ecx,7FFFFF00H
READPCI:add ecx,100H
cmp ecx,80FFFF00H;全读完了?
jnb EXIT;是
mov dx,0CF8H
mov eax,ecx
cli
out dx,eax
mov dx,0CFCH
in eax,dx
sti
cmp eax,0FFFFFFFFH;无效设备?
je READPCI;是
push ecx
mov di,offset venid
cld
PCISTR: mov eax,ecx
mov dx,0CF8H
cli
out dx,eax
mov dx,0CFCH
insd
sti
add cl,4
cmp cl,0FCH;读完256字节数据?
jb PCISTR;否
;=======查找匹配的记录
mov bx,offset hwdb
L0: xor di,di;指向新记录首字节
mov chkok,di;匹配标志清零
L1: mov al,[bx][di]
cmp al,0FFH;读完所有记录?
je UNKNOW;是
mov dx,chkok
cmp al,'$';本记录尾部?
jne L3;否
cmp dx,1;该记录匹配?
je DISP;是
L2: inc di
add bx,di;bx指向下一记录
jmp L0
L3: cmp dx,0FFFFH;本记录不匹配?
jne L5;否。是的话直到下一条记录之前不再进行匹配尝试
L4: inc di
jmp L1
L5: cmp al,'_';有可能是硬件信息?
jne L4;否
mov eax,[bx][di-3]
cmp eax,'_NEV';后面的是VEN信息?
je CHKVEN
cmp eax,'_VED';后面的是DEV信息?
je CHKDEV
cmp eax,'_SYS';后面的是SUBSYS信息?
je CHKSUB
cmp eax,'_VER';后面的是REV信息?
je CHKREV
and eax,0FFFFFF00H
cmp eax,5F434300H;高三位为'_CC';后面的是CLASS信息?
jne L4;都不是
CHKCC: mov eax,[bx][di+1]
call asctohex
mov cx,classid
cmp ax,cx
jz L12
jmp L11
CHKVEN: mov eax,[bx][di+1]
call asctohex
mov cx,venid
cmp ax,cx;与检测到的venid比较
jz L12
jmp L11
CHKDEV: mov eax,[bx][di+1]
call asctohex
mov cx,devid
cmp ax,cx;与检测到的devid比较
jz L12
jmp L11
CHKSUB: mov eax,[bx][di+5]
call asctohex
push di
mov di,offset subsys
mov cx,[di]
pop di
cmp ax,cx;与检测到的subdid比较
jnz L11
mov eax,[bx][di+1]
call asctohex
push di
mov di,offset subsys
mov cx,[di+2]
pop di
cmp ax,cx;与检测到的subvid比较
jnz L11
jmp L12
CHKREV: mov eax,30303030H;为了兼容子过程的处理
mov ax,[bx][di+1]
call asctohex
mov cl,revid
cmp ah,cl;与检测到的rid比较
jz L12
L11: mov dx,0FFFFH
mov chkok,dx;填充不匹配标志
jmp L4
L12: mov dx,1;填充匹配标志
mov chkok,dx
jmp L4
DISP: mov dx,bx
mov ah,9;主要方便输出转向。否则的话稍作修改可以脱离DOS运行。
int 21H
UNKNOW: pop ecx;跳过未匹配设备
jmp READPCI
PCIERR: mov ax,4C01H;非PCI2.0以上版本返回ERRORLEVEL=1
int 21H
EXIT: mov ax,4C00H
int 21H
;把eax的四字节HEX字符串转换成ax数据
asctohex proc near;会破坏edx、ecx、eax内容
;输入:eax待转换值
;返回:ax
push bx
mov cx,4
mov edx,eax
xor eax,eax
S11: mov bl,dl
cmp bl,'9';不做更多判断请务必保证待匹配字串由'0-9、A-F、a-f'组成
jbe S12
and bl,0DFH;转大写字母
sub bl,7
S12: and bl,0FH
shl ax,4
add al,bl
shr edx,8
loop S11
pop bx
ret
asctohex endp
; db 'XXX';用来使后面对齐4的倍数
venid dw 0;pcicfg offset 00H
devid dw 0;pcicfg offset 02H
command_reg dw 0
status_reg dw 0
revid db 0;pcicfg offset 08H
progif db 0;pcicfg offset 09H
classid dw 0;pcicfg offset 0AH
cacheline_size db 0
latency db 0
headtype db 0;pcicfg offset 0EH,=00时SUBSYS有效
bist db 0
baseaddr0 dd 0
baseaddr1 dd 0
baseaddr2 dd 0
baseaddr3 dd 0
baseaddr4 dd 0
baseaddr5 dd 0
cardbus_cis dd 0
subsys dd 0;pcicfg offset 2CH
expansion_ROM dd 0
cap_ptr db 0
reserved1 db 3 dup(0)
reserved2 dd 0
interrupt_line db 0
interrupt_pin db 0
min_grant db 0
max_latency db 0
specific db 192 dup(0)
chkok dw 0;匹配判定标志
hwdbstart db 'HWDBSTART:'
hwdb db 16 dup(' ')
hwdbend db 0FFH
code ends
end START
下面是nforce3-250和mcp51磁盘硬件库示范: