求Win98下面主板Bios读写功能函数outportb,inportb之Delphi函数原型?(100分)

  • 主题发起人 anydelphi
  • 开始时间
你说的CMOS内容我也见到过,但现在记不太清楚了,好象是先往某一端口写一值,再从端
口读内容。仅从对端口的读写角度来说,上面的两个函数肯定没问题,但对于CMOS的读取
则应按其读取要求进行。我不知你是否有相关资料,如有请写出来,我替你把程序写完。
 
program CMOS;
type
TCMOSType = record
Seconds : byte;
SecondAlarm : byte;
Minutes : byte;
MinuteAlarm : byte;
Hours : byte;
HourAlarm : byte;
DayOfWeek : byte;
DayOfMonth : byte;
Month : byte;
Year : byte;
StatusRegA : byte;
StatusRegB : byte;
StatusRegC : byte;
StatusRegD : byte;
DiagStatus : Byte;
ShutDownStatus : Byte;
FloppyDrive : byte;
Reserved1 : byte;
FixedDrive : Byte;
Reserved2 : byte;
Equipment : byte;
RAM : word;
XMS : word;
FixedDriveType1 : byte;
FixedDriveType2 : byte;
Reserved3 : word;
Cylinder1 : word;
Head1 : byte;
WP1 : word;
LZ1 : word;
Sector1 : byte;
Cylinder2 : word;
Head2 : byte;
WP2 : word;
LZ2 : word;
Sector2 : byte;
Sys : byte;
CheckSum : word;
XMS1 : word;
DateCentury : byte;
InfoFlags : byte;
Reserved4: array[1..12] of byte;
end;

TByte64 = array[1..64] of byte;
TCMOS = object
CMOSRec : TCMOSType;
procedure ReadCMOS;
procedure WriteCMOS;
procedure DisplayCMOS;
procedure ModifyCMOS;
procedure ReadFile;
procedure WriteFile;
end;

procedure TCMOS.ReadFile;
var
f1 : file;
data : tbyte64 absolute CMOSRec;
ch : char;
begin
write('Please input the drive name (A/B/C/D): ');
readln(ch);
assign(f1,ch+':/CMOS.DAT');
reset(f1,1);
blockread(f1,data,sizeof(data));
close(f1);
end;

procedure TCMOS.WriteFile;
var
f1:file;
data : tbyte64 absolute CMOSRec;
ch : char;
begin
write('Please input the drive name (A/B/C/D): ');
readln(ch);
assign(f1,ch+':/CMOS.DAT');
rewrite(f1,1);
blockwrite(f1,data,sizeof(data));
close(f1);
end;

procedure TCMOS.ReadCMOS;
begin
asm
les di,self
add di,CMOSRec
MOV CX,40H //64字节数据
MOV AH,0H //
MOV BX,0
@1:
MOV DX,70H
MOV AL,AH
OUT DX,AL
INC DX
in AL,dx
MOV BYTE PTR es:[di+BX],al
INC AH
INC BX
DEC CX
JNZ @1
end;
end;

procedure TCMOS.WriteCMOS;
begin
asm
les di,self
add di,CMOSRec
MOV CX,40H
MOV AH,0H
MOV BX,0
@1:
MOV DX,70H
MOV AL,AH
OUT DX,AL
MOV AL,BYTE PTR es:[di+BX]
INC DX
OUT DX,AL
INC AH
INC BX
DEC CX
JNZ @1
end;
end;

procedure TCMOS.DisplayCMOS;
var
hd1,hd2,fd1,fd2 : byte;
begin
Writeln(^J^M'CMOS RAM information:');
writeln('Date(MM-DD-YY): ',CMOSRec.Month shr 4,CMOSRec.Month and $f,
'-',CMOSRec.DayOfMonth shr 4,CMOSRec.DayOfMonth and $f,
'-',CMOSRec.Year shr 4,CMOSRec.Year and $f);
writeln('Time(HH:MM:SS): ',CMOSRec.Hours shr 4,CMOSRec.Hours and $f,
':',CMOSRec.Minutes shr 4,CMOSRec.Minutes and $f,
':',CMOSRec.Seconds shr 4,CMOSRec.Seconds and $f);
writeln('Conventional Memory: ',CMOSRec.Ram,'KB');
writeln('Extended Memory: ',CMOSRec.XMS,'KB');
hd2 := CMOSRec.FixedDrive and $f;
hd1 := CMOSRec.FixedDrive shr 4;
if (hd1 <> 0) then
begin
writeln('Fixed Drive 1: ',CMOSRec.FixedDriveType1);
writeln(' Cylinder : ',CMOSRec.Cylinder1);
writeln(' Head : ',CMOSRec.Head1);
writeln(' Sector: ',CMOSRec.Sector1);
writeln(' LZ: ',CMOSRec.LZ1);
writeln(' WP: ',CMOSRec.WP1);
end;
if (hd2 <> 0) then
begin
writeln('Fixed Drive 2: ',CMOSRec.FixedDriveType2);
writeln(' Cylinder : ',CMOSRec.Cylinder2);
writeln(' Head : ',CMOSRec.Head2);
writeln(' Sector: ',CMOSRec.Sector2);
writeln(' LZ: ',CMOSRec.LZ2);
writeln(' WP: ',CMOSRec.WP2);
end;
fd2 := CMOSRec.FloppyDrive and $f;
fd1 := CMOSRec.FloppyDrive shr 4;
if (fd1 <> 0) then
begin
write('Floppy Drive 1 : ');
case fd1 of
1 : writeln('360KB 5.25''');
2 : writeln('1.2MB 5.25''');
4 : writeln('1.44MB 3.5''');
6 : writeln('720KB 3.5''');
end;
end ;
if (fd2 <> 0) then
begin
write('Floppy Drive 2 : ');
case fd2 of
1 : writeln('360KB 5.25''');
2 : writeln('1.2MB 5.25''');
4 : writeln('1.44MB 3.5''');
6 : writeln('720KB 3.5''');
end;
end;
end;

procedure TCMOS.ModifyCMOS;
var
hd1,hd2,fd1,fd2 : byte;
data : tbyte64 absolute CMOSRec;
i : word;
begin
Writeln('Please input CORRECT CMOS information !');
write('Conventional Memory (',CMOSRec.ram,'KB): ');readln(CMOSRec.ram);
write('Extended Memory (',CMOSRec.XMS,'KB): ');readln(CMOSRec.XMS);
write('Type of Fixed Disk 1: (',CMOSRec.FixedDriveType1,'): ');readln(CMOSRe
c.FixedDriveType1);
write(' Cylinder (',CMOSRec.Cylinder1,'):'); readln(CMOSRec.Cylinder1);
write(' Head (',CMOSRec.Head1,'): ');readln(CMOSRec.Head1);
write(' Sector (',CMOSRec.Sector1,'): ');readln(CMOSRec.Sector1);
write(' LZ (',CMOSRec.LZ1,'): ');readln(CMOSRec.LZ1);
write(' WP (',CMOSRec.WP1,'): ');readln(CMOSRec.WP1);
write('Type of Fixed Disk 2: (',CMOSRec.FixedDriveType2,'): ');readln(CMOSRe
c.FixedDriveType2);
write(' Cylinder (',CMOSRec.Cylinder2,'):'); readln(CMOSRec.Cylinder2);
write(' Head (',CMOSRec.Head2,'): ');readln(CMOSRec.Head2);
write(' Sector (',CMOSRec.Sector2,'): ');readln(CMOSRec.Sector2);
write(' LZ (',CMOSRec.LZ2,'): ');readln(CMOSRec.LZ2);
write(' WP (',CMOSRec.WP2,'): ');readln(CMOSRec.WP2);
hd1 := 0; hd2 :=0;
if (CMOSRec.FixedDriveType1>46) then hd1 := $f;
if (CMOSRec.FixedDriveType2>46) then hd2 := $f;
CMOSRec.FixedDrive := hd1 shl 4 + hd2;
fd2 := CMOSRec.FloppyDrive and $f;
fd1 := CMOSRec.FloppyDrive shr 4;
write('Floppy Drive 1 (');
case fd1 of
1 : write('360KB 5.25''): ');
2 : write('1.2MB 5.25''): ');
4 : write('1.44MB 3.5''): ');
6 : write('720KB 3.5''): ');
end;
readln(fd1);
write('Floppy Drive 2 (');
case fd2 of
1 : write('360KB 5.25''): ');
2 : write('1.2MB 5.25''): ');
4 : write('1.44MB 3.5''): ');
6 : write('720KB 3.5''): ');
end;
readln(fd2);
CMOSRec.FloppyDrive := fd1 shl 4 + fd2;
CMOSRec.CheckSum := 0;
for i := 17 to 46 do inc(CMOSRec.CheckSum,data);
i := CMOSRec.CheckSum;
data[47] := hi(i);
data[48] := lo(i);
end;
procedure help;
begin
WriteLn('Syntex:'+^J^M+
' CMOS /R --- read information from CMOS RAM '+^J^M+
' and write it to CMOS.DAT file '+^J^M+
' CMOS /W --- read configuration information from CMOS.DAT '+^J^M+
' and write it to CMOS RAM');
Writeln(' CMOS /M --- modify CMOS information and save it'^J^M+
' Floppy Drive Type:'+^J^M+
' 1 : 360KB 5.25'''+^J^M+
' 2 : 1.2MB 5.25'''+^J^M+
' 4 : 1.44MB 3.5'''+^J^M+
' 6 : 720KB 3.5''');
end;
var ch : char;
temp : string;
ICMOS : TCMOS;
begin
WriteLn('CMOS Proctector 1.00, Copyright (c) 1995 Dong Zhanshan');
if paramcount = 1 then
begin
temp := paramstr(1);
ch := upcase(temp[2]);
case ch of
'M' : begin
ICMOS.ReadCMOS;
ICMOS.ModifyCMOS;
ICMOS.DisplayCMOS;
ICMOS.WriteFile;
ICMOS.WriteCMOS;
end;
'R' : begin
ICMOS.ReadCMOS;
ICMOS.DisplayCMOS;
ICMOS.WriteFile;

end;
'W' : begin
ICMOS.ReadFile;
ICMOS.DisplayCMOS;
ICMOS.WriteCMOS;
end;
else help;
end;
end
else
help;
end.
这个程序有错误!
就是 add di,CMOSRec 不知道如何修改??本来想本32汇编回来重新学习的!!
可惜没有找到好的教材,原来在学校的也不知道哪里去了:((

 
to all
高手们:
有什么好的32位汇编教材供学习的??请提供几个,若干年前考汇编
的时候还考了个良,现在全还给书了,不知道是否还能重新找会点感觉!
 
你的出错语句与汇编无关,而与Delphi有关,从语句上看,此语句是取CMOSRec的地址,遗
憾的是,我对Delphi中如何将一个记录的地址传入汇编也不太清楚,更何况这还是一个类中
的记录。我能做的是将CMOS内容读入一个数组中,你自己去数组中将相应数据分离出来。
以读CMOS为例:
var
cmos1:array[0..63] of byte;
procedure TCMOS.ReadCMOS;
begin
asm
les ax,cmos1
mov ds,ax
lea di,cmosrec
MOV CX,40H //64字节数据
MOV AH,0H //
MOV BX,0
@1:
MOV DX,70H
MOV AL,AH
OUT DX,AL
INC DX
in AL,dx
MOV BYTE PTR ds:[di+BX],al
INC AH
INC BX
DEC CX
JNZ @1
end;
end;
读出的数据就依次放在数组CMOS1中,由于我未试验,不知能否实现,主要有两条语句可能
会有问题:
les ax,cmos1
lea di,cmos1
此两语句分别是取数组cmos1的段地址和偏移量,在32位模式下不知是否会有问题,如果还
有问题,我再查查资料。
 
编译没有通过!错误提示跟原来一样的:Operand size mismatch
 
实在不行你就这样干试试(同样以读为例):
var
i:byte
cmos1:array [0..63] of byte;
i:=0;
asm
MOV CX,40H //64字节数据
MOV AH,0H //
MOV BX,0
@1:
MOV DX,70H
MOV AL,AH
OUT DX,AL
INC DX
in AL,dx
MOV cmos1,al
INC AH
INC BX
inc i
DEC CX
JNZ @1
end;

 
MOV cmos1,al Operand size mismatch
 
我发个dll给你哟,其实很简单!
 
好的!ddt_2k1@163.com
 
给我一份
x-delphi@163.com
 
多人接受答案了。
 
端口读写、API HOOK、屏幕取词的完整解决方案见我的《delphi深入windows核心编程》一书,
支持win98/2000/xp,
我的主页http://wenjinshan.yeah.net
 
顶部