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