home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / sampler / 02 / cmos / cmosstuf.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-09-09  |  4.7 KB  |  195 lines

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