home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / DOSTIMU.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  5.2 KB  |  155 lines

  1. /*---------------------------------------------------------------------------
  2.  * filename - dostimu.cas
  3.  *
  4.  * function(s)
  5.  *        __DOStimeToU - converts DOS time to UNIX time
  6.  *--------------------------------------------------------------------------*/
  7.  
  8. /*[]------------------------------------------------------------[]*/
  9. /*|                                                              |*/
  10. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  11. /*|                                                              |*/
  12. /*|                                                              |*/
  13. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  14. /*|     All Rights Reserved.                                     |*/
  15. /*|                                                              |*/
  16. /*[]------------------------------------------------------------[]*/
  17.  
  18.  
  19. #pragma inline
  20. #include <asmrules.h>
  21. #include <_io.h>
  22. #include <time.h>
  23.  
  24. extern unsigned _monthDay[];
  25.  
  26.  
  27. /*--------------------------------------------------------------------------*
  28.  
  29. Name            __DOStimeToU - converts DOS time to UNIX time
  30.  
  31. Usage           long  pascal __DOStimeToU (unsigned long timeStamp);
  32.  
  33. Prototype in    _io.h
  34.  
  35. Description     The timeStamp is a record containing bit-fields with the date
  36.                 and time in the style of PCDOS file time-stamps.
  37.  
  38. Return value    UNIX time: number of seconds since
  39.                        00:00:00 January 1, 1970 (GMT)
  40.  
  41. *---------------------------------------------------------------------------*/
  42. long pascal near __DOStimeToU(unsigned long timeStamp)
  43. {
  44.     unsigned hour, yday, year;
  45.  
  46. asm     mov     cx, W0 (timeStamp)
  47. asm     mov     dx, W1 (timeStamp)
  48.  
  49. asm     mov     si, cx          /* save time in an idle register        */
  50. asm     mov     di, dx          /* save date    */
  51.  
  52. /*
  53.   DX holds the date in compacted form:
  54.  
  55.         yyyyyy mmmm ddddd       year (0 = 1980..119), mon (1..12) day (1..31)
  56.  
  57.   Lets begin by counting the completed days this year.
  58. */
  59. asm     mov     bx, 01E0h
  60. asm     and     bx, dx          /* isolate the month    */
  61. asm     mov     cl, 5
  62. asm     shr     bx, cl
  63. asm     and     dx, 1Fh         /* BX = month 1..12, DX = day 1..31     */
  64.  
  65. asm     mov     cx, 0FE00h
  66. asm     and     cx, di          /* isolate the year     */
  67. asm     shr     cx, 1
  68. asm     xchg    cl, ch          /* CX is now the year since 1980.       */
  69.  
  70. asm     test    cl, 3           /* is this a leap year ?        */
  71. asm     jnz     dtu_notLeapNow
  72. asm     cmp     bl, 2           /* is it later than February ?  */
  73. asm     jna     dtu_notLeapNow
  74. asm     inc     dx              /* add a leap day       */
  75. dtu_notLeapNow:
  76.  
  77. asm     shl     bx, 1
  78. asm     mov     bx, _monthDay [bx - 2]
  79. asm     add     bx, dx
  80. asm     dec     bx              /* BX = completed days only !   */
  81. asm    mov    yday, bx
  82. /*
  83.   Next we need to calculate how many days are counted in the completed
  84.   years since 1970, including 1970.
  85. */
  86. asm     add     cl, 10          /* year since 1970      */
  87. asm    mov    year, cx
  88.  
  89. asm     mov     ax, cx          /* how many leap days occurred ? */
  90. asm     inc     ax              /* count is effectively from 1969.      */
  91. asm     shr     ax, 1
  92. asm     shr     ax, 1           /* divided by 4 */
  93. asm     add     bx, ax          /* add leap days to this year's days    */
  94. /*
  95.   In 130 years (start 1970 .. end 2099) there will be 47,481 days.
  96. */
  97. asm     mov     ax, 365
  98. asm     mul     cx
  99. asm     add     bx, ax          /* 47,481 will fit into 16 bits.        */
  100. /*
  101.   Each day has 86400 seconds.  This is conveniently substituted by
  102.   (2 * 43200).
  103. */
  104. asm     mov     ax, 43200
  105. asm     mul     bx
  106. asm     shl     ax, 1
  107. asm     rcl     dx, 1           /* DX:AX = years counted as seconds     */
  108. /*
  109.   swap out the days' total, fetch today's time
  110. */
  111. asm     xchg    si, ax
  112. asm     mov     bx, dx          /* BX:SI holds years' seconds.  */
  113. /*
  114.   AX = time field, structured as:
  115.  
  116.         hhhhh mmmmmm sssss      hours (0..23), mins (0..59), secs/2 (0..29)
  117. */
  118. asm     push    ax
  119. asm     mov     cl, 3
  120. asm     shr     ax, cl          /* AH = hours   */
  121. asm    mov    byte ptr hour, ah
  122. asm    mov    byte ptr hour+1, 0
  123. asm     dec     cx
  124. asm     shr     al, cl          /* AL = minutes */
  125. asm     mov     cx, 60
  126. asm     xchg    al, cl
  127. asm     mul     ah
  128. asm     add     ax, cx          /* AX = 60*hours + mins = total mins    */
  129. asm     mov     cl, 60
  130. asm     mul     cx
  131. asm     pop     cx
  132. asm     and     cx, 1Fh         /* isolate the two-second counts        */
  133. asm     shl     cx, 1
  134. asm     add     ax, cx
  135. asm     adc     dl, dh          /* DX:AX = seconds in the day   */
  136. asm     add     ax, si
  137. asm     adc     dx, bx          /* DX:AX = total seconds        */
  138. /*
  139.   MSDOS time was local time, so we need to change it to GMT.
  140. */
  141. asm     add     ax, W0 (timezone)
  142. asm     adc     dx, W1 (timezone)
  143. asm     cmp     W0 (daylight), 0
  144. asm    jz    dtu_done    /* skip if DST disabled        */
  145. asm     push    ax
  146. asm    push    dx
  147.     _SI = __isDST( hour, yday, 0, year ) ? 3600 : 0;
  148. asm    pop    dx
  149. asm    pop    ax
  150. asm    sub    ax, si        /* adjust for daylight savings    */
  151. asm    sbb    dx, 0
  152. dtu_done:
  153.         return( MK_LONG );   /* DX:AX contains count of seconds since Unix birthday */
  154. }
  155.