home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 14
/
CD_ASCQ_14_0694.iso
/
maj
/
4151
/
unixdos.asm
< prev
next >
Wrap
Assembly Source File
|
1994-03-22
|
7KB
|
184 lines
title DOS / UNIX FILE TIME CONVERSIONS
page 75,132
; (c) 1991, Mike Dumdei, 6 Holly Lane, Texarkana TX 75503
comment |======================================================================
unsigned long UnixToDos(unsigned *DosTime, unsigned *DosDate,
unsigned long UnixTime);
Converts Unix file time (secs since 1-1-70 GMT) to DOS file time. The
result is stored in the variables pointed to by DosTime and DosDate and
also returned as a long in the form DosDate:DosTime.
unsigned long DosToUnix(unsigned DosTime, unsigned DosDate);
Converts Dos file time to Unix file time. The return value of the
function is the Unix time.
This function does not take into account the difference between the local
time zone and GMT. Both MSC and TC have a 'timezone' variable that may
be used to adjust the UNIX time values. MSC defaults to 28800 or +8 hours
(PST) and TC defaults to 18000 or +5 hours (EST). Zortech C does not have
a timezone variable but functions in it such as 'stat' and 'fstat' that
would normally use 'timezone' have a hard coded value of 25200 or +7 hours
(MST). There is no 'right' value -- it depends on which time zone you are
in and whether or not DST is in effect. If an adjustment to local time is
desired, adjust by the number of minutes local time differs from GMT.
==============================================================================|
IFDEF ??version ;if TASM
MASM51
QUIRKS
ENDIF
IFNDEF model
.MODEL small, C
ELSE
% .MODEL model, C
ENDIF
INCLUDE casm.inc
HICONST EQU 12ceh
LOCONST EQU 0a600h ;secs between 1-1-70 GMT & 1-1-80 GMT
.DATA
DtoUtbl DW 0,31,59,90,120,151,181,212,243,273,304,334
UtoDtbl DB 0,31,28,31,30,31,30,31,31,30,31,30,31
.CODE
UnixToDos PROC, DosTime:PTR, DosDate:PTR, UnixTime:WORD;s = 2 words
mov ax,UnixTime
mov dx,UnixTime[2] ;DX:AX = secs since 1-1-70 GMT
sub ax,LOCONST
sbb dx,HICONST ;DX:AX = secs since 1-1-80 GMT
jnc @F ;jmp if a valid DOS date
xor ax,ax
mov dx,ax ;use 1-1-80 localtime if bad date
@@: shr dx,1
rcr ax,1 ;DX:AX = (secs since 1-1-80) / 2
mov bx,43200 ;BX = secs in a day / 2
div bx ;AX = days, DX = secs / 2 remaining
push dx ;save (partial day secs / 2)
xor dx,dx
mov bx,1461 ;BX = days in 4 year span
div bx ;AX = 4 year spans, DX = excess days
mov bx,OFST UtoDtbl ;BX = pointer to days in months array
shl ax,1
shl ax,1 ;AX = years in complete 4 year spans
inc dx ;days 1 based rather than 0 based
mov cx,366
sub dx,cx ;sub days in first year (leap year)
ja @F ;jmp if not a leap year
mov BPTR [bx+2],29 ;Feb has 29 days if leap year
jmp s calc_month
mov BPTR [bx+2],28 ;Feb has 28 days in not a leap year
@@: dec cx
@@: inc ax ;add another year to years since 1980
sub dx,cx ;sub days in a year
ja @B ;loop till get to current year
calc_month:
add dx,cx ;subtracted once too many, add back
xchg ax,dx ;AX=days this year, DX=yrs since 1980
@@: inc bx
sub al,[bx]
sbb ah,dh
or ax,ax
jg @B ;sub days till get to current month
add al,[bx] ;AL = current day
sub bx,OFST UtoDtbl ;BX = current month
mov dh,dl
shl dh,1 ;DX bits 9-15 = year
mov dl,al ;DX bits 0-4 = day
mov cl,5
shl bx,cl
or dx,bx ;DX bits 5-8 = month
pop ax ;AX = partial day secs / 2
push dx ;save completed month,day,year
xor dx,dx
mov bx,1800
div bx ;AX = hours, DX = mins,secs / 2
mov cl,3
shl al,cl
mov bh,al ;BH bits 11-15 = hour
mov ax,dx
mov bl,30
div bl ;AL = mins, AH = secs / 2
mov bl,ah ;BL bits 0-4 = secs / 2
xor ah,ah
mov cl,5
shl ax,cl ;AX bits 5-10 = minute
or ax,bx ;AX = DOS file time
pLes bx,DosTime
mov FP[bx],ax ;store DOS time in return variable
pop dx ;DX = DOS file date
pLes bx,DosDate
mov FP[bx],dx ;store DOS date in return variable
ret ;back to caller
UnixToDos ENDP
DosToUnix PROC, DosTime, DosDate
mov bx,DosDate
mov al,bh
xor ah,ah
shr ax,1 ;AX = DOS year
mov ch,bl
and ch,1fh
dec ch ;CH = DOS day (0 based)
and bx,1e0h
mov cl,5
shr bx,cl
dec bx ;BX = DOS month (0 based)
mov cl,al
add cl,3
shr cl,1
shr cl,1 ;CL = # leap days due to past years
test al,3
jnz @F ;jmp if this isn't a leap year
cmp bl,1
jbe @F ;jmp if not past leap day yet
inc cl ;CL = total leap days
@@: add cl,ch
xor ch,ch ;CX = day of month + all leap days
shl bx,1 ;shift month for word table lookup
add cx,DtoUtbl[bx] ;CX = days this year + leap days
mov dx,365
mul dx ;AX = days due to years
add ax,cx ;AX = total days since 1-1-80
mov dx,43200 ;hour secs / 2 (avoid long multiply)
mul dx ;DX:AX = day secs since 1-1-80 / 2
shl ax,1
rcl dx,1 ;DX:AX = secs in days since 1-1-80
push dx
push ax ;save partial result
mov bx,DosTime
mov al,bh
mov cl,3
shr al,cl ;AL = hours
mov ah,60
mul ah ;AX = mins due to hours
mov dx,bx
and dx,7e0h
mov cl,5
shr dx,cl ;DX = minutes from DosTime
add ax,dx ;AX = total minutes
mov cx,60
mul cx ;DX:AX = secs in hours and mins
and bx,1fh
shl bx,1 ;BX = secs field from DosTime
add ax,bx
adc dx,0 ;DX:AX = total secs from DosTime
pop bx
pop cx ;CX:BX = total secs from DosDate
add ax,bx
adc dx,cx ;DX:AX = tl secs from Dos timestamp
add ax,LOCONST
adc dx,HICONST ;add secs from 1-1-70GMT to 1-1-80GMT
ret ;back to caller
DosToUnix ENDP
END