home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / dossys / cmos / cmosstuf.pas
Encoding:
Pascal/Delphi Source File  |  1989-02-13  |  4.4 KB  |  184 lines

  1. UNIT CMOSStuf;
  2.  
  3. {--------------------}
  4.      INTERFACE
  5. {--------------------}
  6.  
  7. TYPE { Public types }
  8.  CMOSMemRec = RECORD
  9.                ClockRegs       : ARRAY[1..14] OF BYTE;
  10.                Diagnostic      : BYTE;
  11.                ShutdownStatus  : BYTE;
  12.                FloppyDriveType : BYTE;
  13.                Reserved1       : BYTE;
  14.                FixedDriveType  : BYTE;
  15.                Reserved2       : BYTE;
  16.                EquipmentType   : BYTE;
  17.                BaseMemory      : INTEGER;
  18.                ExtendedMemory1 : INTEGER;
  19.                Reserved3       : ARRAY[1..21] OF BYTE;
  20.                CheckSum        : INTEGER;
  21.                ExtendedMemory2 : INTEGER;
  22.                CenturyDate     : BYTE;
  23.                InfoFlag        : BYTE;
  24.                Reserved4       : ARRAY[1..12] OF BYTE
  25.               END; { Record }
  26.  
  27. CONST { Public constants }
  28.  CMOSNoError       = 0;
  29.  CMOSNotAtError    = 1;
  30.  CMOSCheckSumError = 2;
  31.  
  32. FUNCTION CMOSError     : WORD;            { Returns result of CMOS operation }
  33. FUNCTION CMOSIsAnAT    : BOOLEAN;         { Detects if a PC/AT computer      }
  34. PROCEDURE GetCMOSMem(VAR C : CMOSMemRec); { Read CMOS registers              }
  35. PROCEDURE SetCMOSMem(C : CMOSMemRec);     { Write to CMOS registers          }
  36.  
  37.  
  38. {--------------------}
  39.    IMPLEMENTATION
  40. {--------------------}
  41.  
  42. CONST   { Private constants }
  43.  CMOSMemorySize = 64;
  44.  
  45. VAR     { Private variables }
  46.  CMOSErr : WORD;
  47.  
  48. {--------------------}
  49.  
  50. FUNCTION CMOSError : WORD;
  51.  
  52. BEGIN
  53.  CMOSError := CMOSErr;
  54.  CMOSErr   := 0
  55. END; { CMOSError }
  56.  
  57.  
  58. {--------------------}
  59.  
  60. FUNCTION CMOSIsAnAT : BOOLEAN;
  61.  
  62. CONST
  63.  ATSignature       = $FC;
  64.  CMOSMachIDSeg     = $F000;
  65.  CMOSMachIDOfs     = $FFFE;
  66.  
  67. BEGIN
  68.  CMOSIsAnAT := (MEM[CMOSMachIDSeg : CMOSMachIDOfs] = ATSignature)
  69. END; { CMOSIsAnAT }
  70.  
  71.  
  72. {--------------------}
  73.  
  74. PROCEDURE ComputeCMOSCheckSum(VAR C : CMOSMemRec);
  75.  
  76. VAR
  77.  i : INTEGER;
  78.  
  79. BEGIN
  80.  WITH C DO
  81.   { Calculate the sum of the designated bytes }
  82.   BEGIN
  83.    CheckSum := FloppyDriveType + Reserved1 + FixedDriveType
  84.              + Reserved2 + EquipmentType
  85.              + LO(BaseMemory) + HI(BaseMemory)
  86.              + LO(ExtendedMemory1) + HI(ExtendedMemory1);
  87.  
  88.    FOR i := 1 TO 21 DO
  89.     CheckSum := CheckSum + Reserved3[i];
  90.  
  91.    { Checksum isn't a true integer, so swap hi and lo bytes }
  92.    CheckSum := SWAP(CheckSum)
  93.   END
  94. END; { ComputeCMOSCheckSum }
  95.  
  96.  
  97. {--------------------}
  98.  
  99. FUNCTION ReadCMOSPort(PortNum : BYTE) : BYTE;
  100.  
  101. CONST
  102.  CMOSLatch  = $70;
  103.  CMOSIOPort = $71;
  104.  
  105. BEGIN
  106.  PORT[CMOSLatch] := PortNum;
  107.  ReadCMOSPort    := PORT[CMOSIOPort]
  108. END; { ReadCMOSPort }
  109.  
  110.  
  111. {--------------------}
  112.  
  113. PROCEDURE WriteCMOSPort(PortNum : BYTE;   { Register address within port }
  114.                         Data    : BYTE);  { Data to be written           }
  115.  
  116. CONST
  117.  CMOSLatch  = $70;
  118.  CMOSIOPort = $71;
  119.  
  120. BEGIN
  121.  PORT[CMOSLatch]  := PortNum;
  122.  PORT[CMOSIOPort] := Data
  123. END; { WriteCMOSPort }
  124.  
  125.  
  126. {--------------------}
  127.  
  128. PROCEDURE GetCMOSMem(VAR C : CMOSMemRec);
  129.  
  130. VAR
  131.  i      : INTEGER;
  132.  VarSeg : WORD;
  133.  VarOfs : WORD;
  134.  
  135. BEGIN
  136.  IF CMOSIsAnAT
  137.   THEN BEGIN
  138.         VarSeg := Seg(C);                     { Find location of C     }
  139.         VarOfs := Ofs(C);
  140.         FOR i := 0 TO CMOSMemorySize - 1 DO   { Read record into C     }
  141.          MEM[VarSeg : VarOfs + i] := ReadCMOSPort(i);
  142.         CMOSErr := CMOSNoError
  143.        END
  144.   ELSE CMOSErr := CMOSNotATError
  145. END; { GetCMOSMem }
  146.  
  147.  
  148. {--------------------}
  149.  
  150. PROCEDURE SetCMOSMem(C : CMOSMemRec);
  151.  
  152. VAR
  153.  i       : INTEGER;
  154.  VarSeg  : WORD;
  155.  VarOfs  : WORD;
  156.  TestRec : CMOSMemRec;
  157.  
  158. BEGIN
  159.  IF CMOSIsAnAT
  160.   THEN BEGIN
  161.         ComputeCMOSCheckSum(C);               { Calculate new checksum }
  162.         VarSeg := Seg(C);                     { Find location of C     }
  163.         VarOfs := Ofs(C);
  164.         FOR i := 0 TO CMOSMemorySize - 1 DO   { Move record into CMOS  }
  165.          WriteCMOSPort(i, MEM[VarSeg : VarOfs + i]);
  166.         GetCMOSMem(TestRec);                  { Read record back,      }
  167.         ComputeCMOSCheckSum(TestRec);         { and compare checksums  }
  168.         IF (TestRec.CheckSum = C.CheckSum)
  169.          THEN CMOSErr := CMOSNoError
  170.          ELSE CMOSErr := CMOSCheckSumError
  171.        END
  172.   ELSE CMOSErr := CMOSNotATError
  173. END; { SetCMOSMem }
  174.  
  175.  
  176. {====================}
  177. {   INITIALIZATION   }
  178. {====================}
  179.  
  180. BEGIN
  181.  CMOSErr := CMOSNoError        { Initialize error variable   }
  182. END.
  183. 
  184.