home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / DOSTIMU.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  4.9 KB  |  158 lines

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