home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / resetclk.zip / RESETCLK.TXT < prev   
Text File  |  1991-08-14  |  10KB  |  241 lines

  1. The following text and the code for this COM file were written by Ralph
  2. Wyatt. He has given me permission to distribute it as FREEWARE. Call
  3. this com program at the end of a BAT file that launches a game that
  4. alters the computer clock without resetting it. LEMMINGS and Apogee's
  5. DUKE NUKEM are 2 games that I use this file on.
  6.  
  7.  
  8. This program "RESETCLK.COM" reads the current time and date from
  9.  CMOS RAM in order to automatically restore the correct time of
  10.  day in AT systems where the time has been lost or corrupted.
  11.  
  12. CMOS RAM is an acronym for Complimentary Metal Oxide
  13.  Semiconductor Random Access Memory. It is an integral part of
  14.  all AT class systems, but doesn't occupy any of the base 1Mb of
  15.  address space. It is non-volatile and will retain its "memory"
  16.  as long as the battery in the AT remains charged.
  17.  
  18. This "external" RAM is accessed through hardware ports 70H-7FH.
  19.  However, only ports 70H and 71H are used for our purpose here.
  20.  Information is written to or read from the CMOS RAM by first
  21.  sending an address to port 70H. This "conditions" the MC-146818
  22.  processor for the next event which can be either a read or a
  23.  write operation at port 71H, depending on whether an IN or an
  24.  OUT instruction is issued by the main CPU.
  25.  
  26. Writes to port 71H are just a little bit trickier than reads in
  27.  that a little further "conditioning" of the MC-146818 processor
  28.  is needed. In this program, we're only going to be reading from
  29.  port 71H, so I'll not go into the necessary settings of the
  30.  various status registers in the MC-146818 to accomplish writing
  31.  to the CMOS RAM.
  32.  
  33. The addresses within the MC-146818 that we're interested in for
  34.  this project are:
  35.  
  36.   Byte    Contents
  37.  
  38.    0       Current Second
  39.    2       Current Minute
  40.    4       Current Hour
  41.    7       Day of Month
  42.    8       Month of Year
  43.    9       Year of Century
  44.  
  45. Another byte which could be of interest is byte 50 which
  46.  contains the 2-digit century. For purposes of this program, I
  47.  think it is safe to assume 1900 as the century, so we'll not
  48.  access byte 50.
  49.  
  50. The data at these memory locations can be in either binary or
  51.  packed Binary Coded Decimal (BCD) and the method used to store
  52.  the data is available as a bit switch in one of the Status
  53.  Registers within the Real Time Clock (RTC) which is an integral
  54.  component of the Motorola MC-146818 Processor. During boot, the
  55.  BIOS sets this switch so data are stored in packed BCD.
  56.  
  57. Packed BCD is where a 2-digit decimal number is stored in a
  58.  single byte as a pair of binary integers with the leftmost four
  59.  bits representing the most significant digit and the rightmost
  60.  four bits are the least significant digit.
  61.  
  62. A byte containing the binary representation of the decimal value
  63.  52 in packed BCD would look like: |0101+0010|
  64.                                     5     2
  65.  
  66. A byte containing the straight binary value 52 would look like:
  67.                                   |0011+0100|
  68.  
  69. As you can see, there's quite a difference. Part of our problem
  70.  in this program is finding a way to convert that packed BCD data
  71.  coming from the Motorola chip into standard binary data for the
  72.  INTEL chip.
  73.  
  74.  
  75. Now, let's take a look at the program code.
  76.  
  77. Lines 1 thru 8:   These are just the normal assembler directives
  78.                   and the obligatory Jump instruction that is
  79.                   part of almost all programs destined to become
  80.                   .COM modules.
  81.  
  82. Lines 10 thru 16: Local storage to hold the completed (binary)
  83.                   form of the data we read from the RTC.
  84.  
  85. Lines 18 thru 20: Here's a block of code we'll repeat several
  86.                   times in the ensuing lines. First an address
  87.                   value within the RTC is placed in AL. Then a
  88.                   routine is called which will read the value at
  89.                   that address and convert it from BCD to
  90.                   binary. Here we get the current seconds.
  91.  
  92. Lines 22 thru 40: The above sequence is repeated for the
  93.                   remainder of the data of interest from the
  94.                   clock.
  95.  
  96. Lines 42 thru 49: Here we set up for and call DOS to set the
  97.                   BIOS clock to the TIME retrieved from the RTC.
  98.                   Notice that the hundredths of a second are
  99.                   arbitrarily set to 50. It ain't right on, but
  100.                   it's close.
  101.  
  102. Lines 51 thru 58: Here we do the same for the correct DATE. This
  103.                   covers the case where midnight has passed
  104.                   while the BIOS clock was inoperative. Note
  105.                   that we add 1900 to the year as gotten from
  106.                   the RTC. Further note that the year value
  107.                   passed to DOS is a full 16-bit integer whilst
  108.                   all the other values were 8-bit integers.
  109.  
  110. Lines 60 thru 62: Normal end-of-program return to DOS stuff.
  111.  
  112. Lines 64 thru 83: This is the only interesting part of the
  113.                   program. Here's where the address of the data
  114.                   to be read is passed to the RTC, the data is
  115.                   read and finally converted to binary.
  116.  
  117. Lines 66 thru 72: The address which was passed to this routine
  118.                   in AL is passed on to the RTC via the OUT
  119.                   instruction to port 70H. A couple of do-
  120.                   nothing JMP's are issued just to ensure that
  121.                   the Motorola chip has sufficient time to
  122.                   respond. Next the data from the RTC is read
  123.                   into AL via an IN instruction to port 71H.
  124.                   Again, we use a couple of dummy jumps to give
  125.                   the port time to respond.
  126.  
  127. Lines 74 thru 80: Here the BCD digits in AL get converted to an
  128.                   8-bit binary value. First, both the digits are
  129.                   copied to AH. Then the rightmost 4 bits are
  130.                   shifted out, leaving only the most significant
  131.                   digit from AL. Next a mask is logically anded
  132.                   with both registers and we wind up with a four
  133.                   bit binary value in each register with AH and
  134.                   AL respectively holding the tens and units
  135.                   digits of our original BCD number. All that
  136.                   remains is to multiply the tens digit by 10
  137.                   and add it to the units digit. Here a little
  138.                   creative use of the instruction set is made.
  139.                   The ASCII Adjust after Division (AAD)
  140.                   instruction seems tailor made for this
  141.                   situation, though I doubt it was intended by
  142.                   the designers at INTEL to do so. It does the
  143.                   multiplication and addition just like we want
  144.                   though, so we'll happily use it here. It
  145.                   effectively multiplies AH by 10 and adds the
  146.                   result to AL, then sets AH to zero.
  147.                   Perfect! Just what we're looking for. Now, AL
  148.                   contains the binary equivalent of the original
  149.                   BCD data obtained from the RTC.
  150.  
  151.  
  152.  
  153. CSEG               SEGMENT PARA PUBLIC 'CODE'
  154.                    ASSUME CS:CSEG
  155.                    ORG    100H
  156.  
  157. MAIN               PROC
  158.  
  159. BEGIN:
  160.                    JMP    START
  161.  
  162. HOUR               DB     ?                ;CURRENT HOUR IN BINARY
  163. MINUTES            DB     ?                ;        MINUTES
  164. SECONDS            DB     ?                ;        SECONDS
  165.  
  166. MONTH              DB     ?                ;CURRENT MONTH IN BINARY
  167. DAY                DB     ?                ;        DAY
  168. YEAR               DW     ?                ;        YEAR AS 2 DIGITS
  169.  
  170. START:             SUB    AX,AX            ;READ SECONDS FROM
  171.                    CALL   READ_RTC         ; REAL-TIME CLOCK AND
  172.                    MOV    SECONDS,AL       ; CONVERTED RESULT
  173.  
  174.                    MOV    AL,02H
  175.                    CALL   READ_RTC         ;DO SAME FOR MINUTES
  176.                    MOV    MINUTES,AL
  177.  
  178.                    MOV    AL,04H
  179.                    CALL   READ_RTC         ;AND THE HOUR
  180.                    MOV    HOUR,AL
  181.  
  182.                    MOV    AL,07H
  183.                    CALL   READ_RTC         ;NOW THE DAY
  184.                    MOV    DAY,AL
  185.  
  186.                    MOV    AL,08H
  187.                    CALL   READ_RTC         ;MONTH
  188.                    MOV    MONTH,AL
  189.  
  190.                    MOV    AL,09H
  191.                    CALL   READ_RTC         ;AND YEAR
  192.                    MOV    YEAR,AX
  193.  
  194.                    SUB    AX,AX            ;NOW, WE'LL CALL ON
  195.                    MOV    AH,2DH
  196.                    MOV    CH,HOUR          ; DOS TO SET THE
  197.                    MOV    CL,MINUTES
  198.                    MOV    DH,SECONDS       ; CORRECT TIME
  199.                    MOV    DL,50
  200.  
  201.                    INT    21H              ;SET THE TIME
  202.  
  203.                    SUB    AX,AX            ;NEXT, WE'LL
  204.                    MOV    AH,2BH           ; DO THE SAME
  205.                    MOV    CX,1900          ; FOR THE DATE
  206.                    ADD    CX,YEAR          ; IN CASE WE'VE
  207.                    MOV    DH,MONTH         ; PASSED MIDNIGHT
  208.                    MOV    DL,DAY           ; WITH INCORRECT TIME
  209.  
  210.                    INT    21H              ;SET THE DATE
  211.  
  212.                    MOV    AX,4C00H         ;RETURN TO DOS
  213.                    INT    21H              ; WITH A ZERO ERRORLEVEL
  214.                    ENDP
  215.  
  216. READ_RTC           PROC
  217.  
  218.                    OUT    70H,AL           ;LET PORT 70 KNOW WHAT
  219.                    JMP    $+2              ; ADDRESS WE WANT AND
  220.                    JMP    $+2              ; GIVE IT TIME TO RESPOND
  221.  
  222.                    IN     AL,71H           ;GET DATA FROM THE
  223.                    JMP    $+2              ; REAL TIME CLOCK AND
  224.                    JMP    $+2              ; GIVE IT TIME TO RESPOND
  225.  
  226.                    MOV    AH,AL            ;COPY BCD INFO TO AH
  227.                    SHR    AH,1             ; AND SHIFT OUT
  228.                    SHR    AH,1             ; THE LEAST SIGNIFICANT
  229.                    SHR    AH,1             ; DIGIT, THEN CONVERT
  230.                    SHR    AH,1             ; BOTH UNPACKED BCD
  231.                    AND    AX,0F0FH         ; DIGITS TO BINARY
  232.                    AAD                     ; IN AL
  233.  
  234.                    RET
  235.                    ENDP
  236.  
  237. CSEG               ENDS
  238.                    END    BEGIN
  239.  
  240.  
  241.