home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / SYSTEM / MMCLK12.ZIP / TIME.ASM < prev   
Encoding:
Assembly Source File  |  1990-03-27  |  4.4 KB  |  192 lines

  1.     include    mmclock.mac
  2.     title    MM58167A time routines -- Copyright 1990 Wales
  3.  
  4. ; ======================================================================
  5. ;
  6. ; Time routines for the MM58167A clock/calendar.
  7. ; (C) Copyright 1990 Richard B. Wales.  All Rights Reserved.
  8. ;
  9. ; Global variables:
  10. ;
  11. ;    bcd2bin
  12. ;        A translation table which maps BCD values into binary.
  13. ;
  14. ;    bin2bcd
  15. ;        A translation table which maps binary values into BCD.
  16. ;
  17. ; Global routines:
  18. ;
  19. ;    GetTime
  20. ;        Reads the real-time clock.
  21. ;
  22. ;    SetTime
  23. ;        Sets the real-time clock.
  24.  
  25. ; ======================================================================
  26. ;
  27. ; Global symbols.
  28.  
  29.     public    GetTime, SetTime, bcd2bin, bin2bcd
  30.  
  31. ; ======================================================================
  32. ;
  33. ; XLAT table for converting BCD to binary.
  34. ; NOTE:  This table is only long enough for valid input values.
  35.  
  36. bcd2bin:
  37.     TENS=0
  38.     rept    10
  39.       UNITS=0
  40.       rept 10
  41.         db    (10*TENS) + UNITS
  42.         UNITS=UNITS+1
  43.       endm
  44.       if TENS LT 9
  45.         db    6 dup (255)
  46.       endif
  47.       TENS=TENS+1
  48.     endm
  49.  
  50. ; ======================================================================
  51. ;
  52. ; XLAT table for converting binary to BCD.
  53. ; NOTE:  This table is only long enough for valid input values.
  54.  
  55. bin2bcd:
  56.     TENS=0
  57.     rept    10
  58.       UNITS=0
  59.       rept 10
  60.         db    (16*TENS) + UNITS
  61.         UNITS=UNITS+1
  62.       endm
  63.       TENS=TENS+1
  64.     endm
  65.  
  66. ; ======================================================================
  67. ;
  68. ; GetTime
  69. ;
  70. ;    Read the time-of-day info from the clock.
  71. ;
  72. ;    Arguments:
  73. ;
  74. ;        DX    Should be set to the initial I/O port address
  75. ;            for the clock.
  76. ;
  77. ;    Returned values:
  78. ;
  79. ;        CH    Hours (0-23).
  80. ;        CL    Minutes (0-59).
  81. ;        DH    Seconds (0-59).
  82. ;        DL    Hundredths of a second (0-99).
  83.  
  84. GetTime    proc    near
  85.  
  86.     ; Set up the loop count.
  87.     mov    cx, MAX_RETRIES
  88.  
  89.     ; We'll skip the milliseconds position in the counter.
  90.     inc    dx
  91.  
  92. read_again:
  93.     ; Read the counter info from the clock.  Finish up by re-reading
  94.     ; the 1/100 second info and comparing it with the value originally
  95.     ; read from this position.  The 1/100 second position must be read
  96.     ; first, and must therefore be read via a byte-sized IN, since
  97.     ; some AT-clones don't read the ports in IBM-compatible (lower
  98.     ; port first) order.
  99.     mov    bp, cx                  ; save loop counter
  100.     INBR    bl            ; 1/100 seconds (save in BL)
  101.     inc    dx
  102.     INBR    bh            ; seconds (save in BH)
  103.     inc    dx
  104.     INWR    cx            ; hours/minutes (save in CX)
  105.     dec    dx
  106.     dec    dx            ; back to start of counter
  107.     INBR    al            ; re-read 1/100 second
  108.     cmp    al, bl            ; compare with saved value
  109.     jne    short read_ticked    ; if changed, try again
  110.     mov    dx, bx            ; move seconds to right place
  111.  
  112.     ; Convert everything from BCD to straight binary.
  113.     INIT_DS
  114.     mov    bx, offset bcd2bin
  115.     XLATCK    cx, cx, 23, 59, bad_read ; hours/minutes
  116.     XLATCK    dx, dx, 59, 99, bad_read ; seconds
  117.     ret
  118.  
  119. read_ticked:
  120.     ; The counter rolled over while we were reading it.  Try again.
  121.     mov    cx, bp            ; restore loop counter
  122.     loop    short read_again
  123.  
  124. bad_read:
  125.     ; In case of failure, return "midnight".
  126.     xor    cx, cx
  127.     xor    dx, dx
  128.     ret
  129.  
  130. GetTime    endp
  131.  
  132. ; ======================================================================
  133. ;
  134. ; SetTime
  135. ;
  136. ;    Write the time-of-day info to the clock.
  137. ;
  138. ;    Arguments:
  139. ;
  140. ;        CH    Hours (0-23).
  141. ;        CL    Minutes (0-59).
  142. ;        DH    Seconds (0-59).
  143. ;        DL    Hundredths of a second (0-99).
  144. ;        BP    Should be set to the initial I/O port address
  145. ;            for the clock.
  146. ;
  147. ;    Returned values:
  148. ;
  149. ;        None.
  150.  
  151. SetTime    proc    near
  152.  
  153.     ; Validate the input and convert from BCD to binary.
  154.     INIT_DS
  155.         mov    bx, offset bin2bcd
  156.     CKXLAT    cx, si, 23, 59, bad_write
  157.     CKXLAT    dx, di, 59, 99, bad_write
  158.  
  159.         ; Write the counter info to the clock.  Finish up by re-reading
  160.     ; the first counter byte (1/100 second) and making sure it has
  161.     ; not changed.
  162.     mov    dx, bp            ; I/O port
  163.     mov    cx, MAX_RETRIES        ; loop count
  164. write_again:
  165.     xor    ax, ax            ; 1/1000 second (always zero)
  166.     OUTBR    al
  167.     inc    dx
  168.     OUTWR    di            ; seconds and 1/100 second (DI)
  169.     inc    dx
  170.     inc    dx
  171.     OUTWR    si            ; hours and minutes (SI)
  172.     dec    dx
  173.     dec    dx            ; back to 1/100 second position
  174.     mov    ax, di
  175.     INBR    al            ; re-read 1/100 second
  176.     dec    dx            ; back to 1/1000 second position
  177.     cmp    ax, di            ; 1/100 sec should be unchanged;
  178.     jnz    short write_ticked    ;     if not, try again
  179.     ret
  180.  
  181. write_ticked:
  182.     ; The counter rolled over while we were writing.  Try again.
  183.     loop    short write_again
  184.  
  185. bad_write:
  186.     ret
  187.  
  188. SetTime    endp
  189.  
  190. code    ends
  191.  
  192.     end