讀寫CMOS內(nèi)存
發(fā)表時(shí)間:2023-08-06 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]一、CMOS內(nèi)存信息詳解 一般的PC/AT、286、386、486等微機(jī)均配有CMOS芯片,CMOS&127;芯片包含了一個(gè)實(shí)時(shí)鐘和64個(gè)字節(jié)的CMOS內(nèi)存。在CMOS內(nèi)存中,0-0DH為實(shí)...
一、CMOS內(nèi)存信息詳解
一般的PC/AT、286、386、486等微機(jī)均配有CMOS芯片,CMOS&127;芯片包含了一個(gè)實(shí)時(shí)鐘和64個(gè)字節(jié)的CMOS內(nèi)存。在CMOS內(nèi)存中,0-0DH為實(shí)時(shí)鐘的有關(guān)信息,0E-&127;3FH包含計(jì)算機(jī)的硬件配置信息,如常規(guī)內(nèi)存的大小、擴(kuò)展內(nèi)存的大小、&127;軟盤的類型、固定盤的類型及其物理參數(shù)、顯示器的類型等,這些參數(shù)與計(jì)算機(jī)能否正常工作具有密切的關(guān)系,另外還有計(jì)算機(jī)的開機(jī)口令和其它輔助設(shè)置信息。表1列出了&127;CMOS內(nèi)存各字節(jié)的用途。
表1 CMOS內(nèi)存配置信息的含義
地 址 功能 說明
0,1 秒,秒報(bào)警
2,3 分,分報(bào)警
4,5 時(shí),時(shí)報(bào)警
6 星期幾
7,8,9 日,月,年
A 狀態(tài)寄存器A
B 狀態(tài)寄存器B
C 狀態(tài)寄存器C
D 狀態(tài)寄存器D 0=電池失效,80=電池有效
E 診斷狀態(tài)
F 關(guān)機(jī)狀態(tài) 由上電診斷定義
10 軟驅(qū) 高4位為A驅(qū),低4位為B驅(qū),0=無, 1=360KB, 2=1.2KB, 4=1.44KB, 6=720KB
11 保留
12 固定盤 高4位為C驅(qū),低4位為D驅(qū),0=無,F=用戶定義盤, 其它為系統(tǒng)定義盤
13 保留
14 設(shè)備狀態(tài) 標(biāo)志驅(qū)動(dòng)器數(shù)、顯示器類型、有無數(shù)學(xué)處理器等
15-16 內(nèi)存 以KB計(jì)的常規(guī)內(nèi)存數(shù),100H=256KB,200H=512KB, 280H=640KB
17-18 擴(kuò)展內(nèi)存 以KB計(jì)的擴(kuò)展內(nèi)存數(shù),200H=512KB,400H=1024KB等
19 C盤類型數(shù) 根據(jù)具體硬盤類型而定
1A D盤類型數(shù) 根據(jù)具體硬盤類型而定
1B-1C 保留
1D-1E C盤柱體數(shù) 1D-2CH只有當(dāng)硬盤為用戶自定義類型時(shí)起作用
1F C盤面數(shù)
20-21 C盤WP
22-23 C盤LZ
24 C盤每柱扇區(qū)
25-26 D盤柱體數(shù)
27 D盤面數(shù)
28-29 D盤WP
2A-2B D盤LZ
2C D盤每柱扇區(qū)
2D 保留
2E-2F 校驗(yàn)和 為10-2DH共30個(gè)字節(jié)的和數(shù),2EH為高位,2FH為低位
30-31 擴(kuò)展內(nèi)存
32 日期的世紀(jì)數(shù) BCD碼的世紀(jì)值,如1995年的世紀(jì)數(shù)為19
33 標(biāo)志信息
34-3F 保留
*地址欄均為16進(jìn)制表示
二、讀寫CMOS內(nèi)存的方法
CMOS內(nèi)存的地址口和數(shù)據(jù)口的口地址分別為70H和71H。在對(duì)CMOS內(nèi)存進(jìn)行寫操作時(shí),首先將要寫入的CMOS內(nèi)存的地址送到口地址70H,&127;再將要寫入的數(shù)據(jù)送口地址71H。在對(duì)CMOS內(nèi)存進(jìn)行讀操作時(shí),首先將要讀出的CMOS內(nèi)存的地址送到口地址70H,再從口地址71H讀出數(shù)據(jù)到AL寄存器。
三、程序設(shè)計(jì)與使用
為了方便系統(tǒng)信息丟失后CMOS信息的恢復(fù),作者用BORLAND PASCAL&127;設(shè)計(jì)了一個(gè)CMOS.PAS的程序,它可以將CMOS內(nèi)存中的信息直接寫入文件,也可以把文件中的信息寫入CMOS內(nèi)存,同時(shí)可以對(duì)CMOS內(nèi)存中的信息進(jìn)行編輯修改,并重新寫回CMOS內(nèi)存。它不僅解決了沒有SETUP程序的計(jì)算機(jī)在加電時(shí)不能設(shè)置CMOS內(nèi)存的問題,同時(shí)解決了CMOS信息的保存和恢復(fù)問題,是廣大計(jì)算機(jī)用戶的一個(gè)好幫手。
該程序的使用很簡單,在DOS提示符下打CMOS,即顯示該程序的使用方法,&127;具體使用方法是:
CMOS [/開關(guān)]
開關(guān)有3個(gè):
R --- 讀取CMOS內(nèi)存信息,并將其存入CMOS.DAT的文件,共占64個(gè)字節(jié)。
W --- 從CMOS.DAT中讀取信息,并將其寫入CMOS內(nèi)存。&127;注意這樣寫入的CMOS信息,其時(shí)間和日期是不正確的,寫完之后應(yīng)當(dāng)用DOS命令DATE和TIME&127;設(shè)置正確的日期和時(shí)間。
M --- 從CMOS中讀取當(dāng)前信息,進(jìn)行修改,然后將其寫入CMOS內(nèi)存和CMOS.DAT的文件。
四、程序清單
由于篇幅的限制,程序中略去了用TURBO &127;VISION&127;編寫的程序界面部分。
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
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]);
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.