程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 讀寫CMOS內存

讀寫CMOS內存

編輯:Delphi
一、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. 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved