home *** CD-ROM | disk | FTP | other *** search
- ;========================================================================
-
- ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
-
- .386
- even
- RespondingIpNr dw 0, 0
-
- TservNum dw 0
- TimeServIpNr dw MAXTSERVS*2 dup(0)
-
- Sday equ 3600*24
-
- days macro incval
- dd x*Sday
- x = x+incval
- endm
-
- Ytab:
- x = 15*366 + 49*365 ; start at 1964
- rept 16
- days 366
- days 365
- days 365
- days 365
- endm ; ends on year 2027
-
- Motab: ; normal year
- x = 0
- days 31 jan
- days 28 feb
- days 31 mar
- days 30 apr
- days 31 may
- days 30 jun
- days 31 jul
- days 31 aug
- days 30 sep
- days 31 oct
- days 30 nov
- days 31 dec
- days 1
-
- Mltab: ; leap yer
- x = 0
- days 31 jan
- days 29 feb
- days 31 mar
- days 30 apr
- days 31 may
- days 30 jun
- days 31 jul
- days 31 aug
- days 30 sep
- days 31 oct
- days 30 nov
- days 31 dec
- days 1
-
- Weekdays db " Sun"
- db " Mon"
- db " Tues"
- db "Wednes"
- db " Thurs"
- db " Fri"
- db " Satur"
-
-
- AlgTab AlgData <>
- AlgTabEnd equ $
-
- AlgPtr dw 0
-
- cWday dw 0
- cYear dw 0
- cMonth dw 0
- cDay dw 0
- cHour dw 0
- cMinute dw 0
- cSecond dw 0
-
- cNonLeapYear db 0, 0
- cDayOfYear dw 0
- cTime dw 0, 0
- AlterTime dw 0, 0, 0
- tzoffset dw 0, 0
- DstAdvance dw 0, 0
-
- m6hour dw 6*3600
- m12hour dw 12*3600
- mhour dw 3600
- m60b db 60,0
- m7 dw 7
- m1 dw 1
- m18 dw 18
- m6 db 6
-
- msgweek = $+13
- msgyear = $+23
- msghour = $+37
- msgset db 'Clock set to Wednesday 1989-10-21 at 18:21:15'
- msgts = $+11
- db ' from host 1.2.3.4 ', '$'
-
- MsgNotSet db CR, LF
- db "***************************************", CR, LF, 7
- db "* *", CR, LF
- db "* Could not set correct date and time *", CR, LF
- db "* *", CR, LF
- db "***************************************", CR, LF, "$"
-
-
- .8086
-
- ;************************************************************************
- ;* SearchAndSub
- ;*
- ;* Find lowest index table entry with value (in seconds) <= DX,AX
- ;* and subtract off table value from DX,AX.
- ;************************************************************************
-
- assume ds:code_s
-
- SearchAndSub proc near
- call BinSearch
- call AfterSearch
- ret
- SearchAndSub endp
-
-
-
- BinSearch proc near
- push bx
- mov bx,cx ; compute power of 2
- mov cx,4 ; table size
- BinLenLoop:
- shl cx,1
- cmp cx,bx
- jb BinLenLoop
-
- mov bx,cx ; start binary search
- BinLess:
- sub bx,cx
- BinGreater:
- shr cx,1
- cmp cx,4
- jb BinDone ; no match return
-
- add bx,cx
- cmp dx,2[si+bx]
- BinEval:
- ja BinGreater
- jb BinLess
-
- cmp ax,[si+bx]
- ja BinGreater
- jb BinLess
- BinDone:
- mov cx,bx ; save table index
- lea si,[si+bx] ; and table entry address
- pop bx
- ret
- BinSearch endp
-
-
-
- AfterSearch proc near
- sub ax,[si] ; subtract seconds
- sbb dx,2[si] ; by table value
- shr cx,1 ; calculate table index
- shr cx,1
- ret
- AfterSearch endp
-
-
-
- ;************************************************************************
- ;* DateTimeCalc
- ;************************************************************************
-
- DateTimeCalc proc near
- mov ax,bx
- mov dx,cx
- push si
- push ax ; save seconds since
- push dx ; year 1900
-
- mov si,offset Ytab
- mov cx,4*64
- call SearchAndSub ; find and subtract years
- add cx,1964
- mov cYear,cx ; set year
-
- push ax ; reminder still too big
- push dx ; for 16 bits,
- shr dx,1 ; have to
- rcr ax,1 ; divide by 2
- div m12hour
- inc ax
- mov cDayOfYear,ax ; set day within year
-
- pop dx ; restore seconds within year
- pop ax
-
- and cl,011b ; extract leap year index
- mov cNonLeapYear,cl
- mov si,offset Motab
- jnz NoLeapYear
- mov si,offset Mltab
- NoLeapYear:
- mov cx,4*16
- call SearchAndSub ; find and subtract month
- inc cx
- mov cMonth,cx ; set month within year
-
- shr dx,1 ; reminder still too big
- rcr ax,1 ; for 16 bits, have to
- rcr bx,1 ; divide by 2
- div m12hour ; divide by 24hr/2
- inc ax
- mov cDay,ax ; set day within month
-
- mov ax,dx
- xor dx,dx
- shl bx,1 ; recover lost bit
- rcl ax,1 ; into reminder
- rcl dx,1
- div mhour ; divide by 3600
- mov cHour,ax ; set hour within day
-
- mov ax,dx
- div m60b ; divide by 60
- mov dl,ah
- xor dh,dh
- mov cSecond,dx ; set second within minute
- xor ah,ah
- mov cMinute,ax ; set minute within hour
-
- pop dx ; restore seconds since
- pop ax ; year 1900
- shr dx,1 ; too big for 16 bits...
- rcr ax,1
- div m12hour ; calculate days since 1900
- inc ax
- xor dx,dx ; calculate weeks since 1900
- div m7
- mov cWday,dx ; set weekday
- pop si
- ret
- DateTimeCalc endp
-
-
-
- ;************************************************************************
- ;* SetTime
- ;************************************************************************
-
- SetTime proc near
- push cs
- push cs
- pop ds
- pop es
- cld
- ; convert from network byte
- mov cx,cTime ; order
- xchg ch,cl
- mov bx,cTime+2
- xchg bh,bl
-
- mov dx,tzoffset+2 ; and apply time zone
- xchg dh,dl
- sub bx,dx
- mov ax,tzoffset ; offset
- xchg ah,al
- sbb cx,ax
-
- mov ax,AlterTime ; add alter-days
- imul m6hour
- shl ax,1
- rcl dx,1
- shl ax,1
- rcl dx,1
- add bx,ax
- adc cx,dx
-
- mov ax,AlterTime+2 ; add alter-time
- mov dx,AlterTime+4
- add bx,ax
- adc cx,dx
-
- mov si,AlgPtr
- or si,si ; any daylight algorithm?
- jnz DoDls
- jmp SetNoDls
- DoDls:
- push bx
- push cx
- add si,4
- lodsw ; from switching time
- imul m1
- sub bx,ax
- sbb cx,dx
-
- call DateTimeCalc ; dst start evaluation
-
- cmp si,offset AlgTab.Apa0 ; four entry part?
- jl SingleEntry
-
- mov al,AlgEntryLen
- mul cNonLeapYear
- add si,ax
- cmp si,offset AlgTab.Ais0 ; acyclic entry?
- jb SingleEntry
-
- cmp cYear,WARNYEAR
- jb SingleEntry
-
- mov MsgTermStop,' ' ; activate warning msg
- SingleEntry:
- mov bp,cDayOfYear
- lodsw ; from switching weekday
- cmp al,SAT
- ja FromDate
- dec bp
- cmp ax,cWday
- jg CurWeekF
- add bp,7
- CurWeekF:
- sub bp,cWday
- add bp,ax
- FromDate:
- pop cx
- pop bx
- push bx
- push cx
- lodsw ; from switching week
-
- push ax
- lodsw ; until switching time
- imul m1
- sub bx,ax
- sbb cx,dx
-
- call DateTimeCalc ; dst end evaluation
-
- mov di,cDayOfYear
- pop dx
-
- lodsw ; until switching weekday
- cmp al,SAT
- ja UntilDate
- dec di
- cmp ax,cWday
- jg CurWeekU
- add di,7
- CurWeekU:
- sub di,cWday
- add di,ax
- UntilDate:
- lodsw ; until switching week
- test cNonLeapYear,011b
- jnz SetNotLeap
- cmp ax,31+28
- jbe SetChkLU
- inc ax
- SetChkLU:
- cmp dx,31+28
- jbe SetNotLeap
- inc dx
- SetNotLeap:
- pop cx
- pop bx
- cmp ax,dx ; north or south of equator?
- jl SetSouth
- cmp dx,bp ; to do or not to do dls?
- jg SetNoDls
- jmp short SetChkUntil
- SetSouth:
- cmp dx,bp ; to do or not to do dls?
- jle DoDLSaving
- SetChkUntil:
- cmp di,ax
- jge SetNoDls
- DoDLSaving:
- or GenFlags,DSTNOW
- lodsw ; dst advance time
- mov DstAdvance,ax
- imul m1
- add bx,ax
- adc cx,dx
- SetNoDls:
- call DateTimeCalc ; calculate date and time
-
- test Flagword,DONT_SETTIME ; did we use alter argument?
- jz SetPCtime
-
- mov di,offset msgset
- mov cx,12
- mov al,' '
- rep stosb ; clear "Clock set to"
- jmp SkipTimeset
- SetPCtime:
- mov cx,cYear
- mov dh,byte ptr cMonth
- mov dl,byte ptr Cday
- mov ah,2Bh ; set date
- int 21h
- or al,al
- jz DateOK
- mov al,5 ; error code 5
- call Terminate
- DateOK:
- mov ch,byte ptr cHour
- mov cl,byte ptr cMinute
- mov dh,byte ptr cSecond
- mov dl,99
- mov ah,2Dh ; set time
- int 21h
- or al,al
- jz TimeOK
- mov al,6 ; error code 6
- call Terminate
- TimeOK:
- SkipTimeset: ; edit time display msg
- mov al,byte ptr cWday
- mul m6
- add ax,offset Weekdays
- mov si,ax
- mov di,offset msgweek
- mov cx,3
- rep movsw ; copy weekday string
-
- mov si,offset cYear
- mov di,offset msgyear
- mov ch,'-'
- mov cl,3
- call PutNums ; put date
-
- mov di,offset msghour
- mov ch,':'
- mov cl,3
- call PutNums ; put time
-
- mov si,offset RespondingIpNr
- mov di,offset msgts
- call PutIpNum ; put time server IP #
-
- mov dx,offset msgset
- mov ah,9
- int 21h ; display string
-
- ret
- SetTime endp
-
-
-
- ;**********************************************************************
- ;
- ; Timezone environment handling
- ;
- ;**********************************************************************
-
- assume ds:code_s
-
- comment |
- ==========
- tech.notes/pc.code #29, from pmaupin, 3407 chars, Sat Jun 4 22:40:45 1988
- ----------
- TITLE: Finding DOS's master environment pointer
- This is a fragment of code that my SD.COM program uses to find
- the environment. This fragment is different than most ways of
- finding the environment, in that it finds the MASTER environment block,
- not the current process's parent's environment.
-
- This is useful in some cases, and has the added advantage that
- it does NOT behave differently when executing under CodeView,
- so you do NOT have to hard-code your system's DOS environment address
- into your program in order to debug it.
- |
-
- EnvPtr EQU 2CH ; Offset in PSP
-
- CommandInterrupt EQU 2EH ; entry point into first Command.Com
- ; through interpreter
-
- DosSegPtr EQU CommandInterrupt * 4 + 2
-
-
- ; FindEnvironment is passed:
-
- ; DS should point to program PSP
-
- ; FindEnvironment returns:
-
- ; ES points to master environment block, or program's copy if couldn't
- ; find the master.
-
- ; CX is length of block, or 0 if couldn't find the master.
-
- ; FindEnvironment destroys:
-
- ; AX, SI
-
-
- FindEnvironment PROC NEAR
- xor si,si ; Point to segment 0
- mov es,si
- mov si, word ptr es:[DosSegPtr]
- mov ax,si
- call VerifyBlock ; make sure we've found COMMAND
- jnz GotBlock ; jump if not a good block --
- ; use process's environment
-
- mov ax,es:[EnvPtr+10h] ; get COMMAND's environment ptr
- or ax,ax ; jump if COMMAND has a
- jnz MaybeGoodBlock ; subsidiary environment
-
- mov ax,si ; If no subsidiary, just use
- add ax,cx ; the allocation block
- inc ax ; immediately after COMMAND
-
- MaybeGoodBlock: call VerifyBlock ; verify that we have a good
- ; one, one way or another
- GotBlock:
- shl cx,1 ; multiply by 16 to get
- shl cx,1 ; length in bytes
- shl cx,1
- shl cx,1
- mov es,ax
- ret
-
-
- ; VerifyBlock tries to insure that we're pointing to a valid DOS
- ; allocation block. If not, returns the current process's environment
- ; block.
-
-
- VerifyBlock PROC NEAR
- dec ax ; get block header into ES
- mov es,ax
- inc ax
-
- cmp byte ptr es:[0],04Dh ; make sure signature is valid
- jnz UseCurrent
- cmp word ptr es:[1],si ; make sure owner is valid
- jnz UseCurrent
- mov cx, word ptr es:[3] ; retrieve the length
- ret
-
- UseCurrent: mov ax,word ptr ds:[EnvPtr] ; get current process's env
- xor cx,cx ; zero length
- ret
- VerifyBlock ENDP
-
- FindEnvironment ENDP
-
- comment |
- So far, this seems to work. I would welcome any feedback on its
- efficacy, but if the feedback is negative, please give the DOS version
- and a detailed problem description. Thanks,
- Pat
- |
-
- ZoneMsg db CR, LF, "Environment variable "
- ZoneString db "TZ=+0100",0,0,"$ "
- ZONESPACE equ $-ZoneString
- ZoneVarLen dw 3
- ZoneStrLen dw 10
- ZoneDstInd dw 10
-
- ;************************************************************************
- ;* SetZone
- ;*
- ;************************************************************************
-
- assume ds:code_s
-
- SetZone proc near
- test GenFlags,ARGZONE ; anything to SET?
- jnz SetZoneInfo
- ret
-
- SetZoneInfo:
- cld
- test GenFlags,ARGZONESPEC ; extended syntax?
- jnz SetZoneSpecial
-
- mov ax,DstAdvance ; -no, use numeric zones
- xor dx,dx ; compute current time offset
- mov cx,tzoffset
- xchg ch,cl
- mov bx,tzoffset+2
- xchg bh,bl
- sub ax,bx
- sbb dx,cx
- mov cl,'+'
- jns ZonePositive ; current time offset sign?
- mov cl,'-'
- call NegDxAx
- ZonePositive:
- mov di, offset ZoneString
- add di,ZoneVarLen
- mov [di],cl
- div mhour ; compute hours
- push ax
- mov ax,dx
- div m60b ; and minutes
- xor ah,ah
- mov di,offset ZoneString+3
- add di,ZoneVarLen
- mov PutMinDigits,2 ; *test
- call PutNum ; put minutes
- pop ax
- sub di,4
- call PutNum ; put hours
- jmp short EnvMaster
-
- SetZoneSpecial:
- test GenFlags,DSTNOW ; is it normal or dls time?
- jz EnvMaster
- mov di,offset ZoneString ; -dls, copy dls name
- mov si,di ; on top of normal name
- add di,ZoneVarLen
- add si,ZoneDstInd
- SetZoneLoop:
- lodsb
- stosb
- cmp al,0
- jne SetZoneLoop
- stosb
- mov al,'$'
- stosb
- sub di,offset ZoneString+1
- mov ZoneStrLen,di
- EnvMaster:
- call FindEnvironment ; Find master environment
-
- xor di,di
- xor al,al
- EnvNext:
- jcxz EnvNotFound
-
- test FlagWord,DONT_SETTIME
- jnz EnvZonePr
- push cx ; look for TZ=
- push di
- mov cx,ZoneVarLen
- mov si,offset ZoneString
- repe cmpsb
- jnz EnvNoMatch
-
- pop di ; if found, remove whole string
- pop cx
- push cx
- push di
- repne scasb
- mov si,di
- pop di
- push di
- push es
- pop ds
- rep movsb
- push cs
- pop ds
- EnvNoMatch:
- pop di
- pop cx
-
- cmp byte ptr es:[di],0 ; end of strings?
- je EnvEnd
- repne scasb ; -no, skip past this string
- jmp short EnvNext
- EnvEnd:
- cmp cx,ZoneStrLen ; add TZ string to the end
- jb EnvNotFound
- mov cx,ZoneStrLen
- mov si,offset ZoneString
- rep movsb
-
- EnvZonePr:
- mov dx,offset ZoneMsg
- push cs
- pop ds
- mov ah,9
- int 21h ; display env var contents
-
- EnvNotFound:
- push cs ; restore ds and es
- push cs
- pop ds
- pop es
- ret
- SetZone endp
-