home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / PKTDRVR / PDCLK207.ZIP / PDCLKSRC / SETTIME.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-08-01  |  13.9 KB  |  694 lines

  1. ;========================================================================
  2.  
  3. ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
  4.  
  5.         .386
  6.         even
  7. RespondingIpNr    dw    0, 0
  8.  
  9. TservNum    dw    0
  10. TimeServIpNr    dw    MAXTSERVS*2 dup(0)
  11.  
  12. Sday        equ    3600*24
  13.  
  14. days        macro    incval
  15.         dd    x*Sday
  16. x        =    x+incval
  17.         endm
  18.  
  19. Ytab:
  20. x        =    15*366 + 49*365     ; start at 1964
  21.         rept    16
  22.         days    366
  23.         days    365
  24.         days    365
  25.         days    365
  26.         endm                ; ends on year 2027
  27.  
  28. Motab:                        ; normal year
  29. x        =    0
  30.         days    31    jan
  31.         days    28    feb
  32.         days    31    mar
  33.         days    30    apr
  34.         days    31    may
  35.         days    30    jun
  36.         days    31    jul
  37.         days    31    aug
  38.         days    30    sep
  39.         days    31    oct
  40.         days    30    nov
  41.         days    31    dec
  42.         days    1
  43.  
  44. Mltab:                        ; leap yer 
  45. x        =    0
  46.         days    31    jan
  47.         days    29    feb
  48.         days    31    mar
  49.         days    30    apr
  50.         days    31    may
  51.         days    30    jun
  52.         days    31    jul
  53.         days    31    aug
  54.         days    30    sep
  55.         days    31    oct
  56.         days    30    nov
  57.         days    31    dec
  58.         days    1
  59.  
  60. Weekdays    db    "   Sun"
  61.         db    "   Mon"
  62.         db    "  Tues"
  63.         db    "Wednes"
  64.         db    " Thurs"
  65.         db    "   Fri"
  66.         db    " Satur"
  67.  
  68.  
  69. AlgTab        AlgData <>
  70. AlgTabEnd    equ    $
  71.  
  72. AlgPtr        dw    0
  73.  
  74. cWday        dw    0
  75. cYear        dw    0
  76. cMonth        dw    0
  77. cDay        dw    0
  78. cHour        dw    0
  79. cMinute     dw    0
  80. cSecond     dw    0
  81.  
  82. cNonLeapYear    db    0, 0
  83. cDayOfYear    dw    0
  84. cTime        dw    0, 0
  85. AlterTime    dw    0, 0, 0
  86. tzoffset    dw    0, 0
  87. DstAdvance    dw    0, 0
  88.  
  89. m6hour        dw    6*3600
  90. m12hour     dw    12*3600
  91. mhour        dw    3600
  92. m60b        db    60,0
  93. m7        dw    7
  94. m1        dw    1
  95. m18        dw    18
  96. m6        db    6
  97.  
  98. msgweek     =    $+13
  99. msgyear     =    $+23
  100. msghour     =    $+37
  101. msgset        db    'Clock set to Wednesday 1989-10-21 at 18:21:15'
  102. msgts        =    $+11
  103.         db    ' from host 1.2.3.4        ', '$'
  104.  
  105. MsgNotSet    db    CR, LF
  106.         db    "***************************************", CR, LF, 7
  107.         db    "*                                     *", CR, LF
  108.         db    "* Could not set correct date and time *", CR, LF
  109.         db    "*                                     *", CR, LF
  110.         db    "***************************************", CR, LF, "$"
  111.  
  112.  
  113.         .8086
  114.  
  115. ;************************************************************************
  116. ;*        SearchAndSub
  117. ;*
  118. ;* Find lowest index table entry with value (in seconds) <= DX,AX
  119. ;* and subtract off table value from DX,AX.
  120. ;************************************************************************
  121.  
  122.         assume    ds:code_s
  123.  
  124. SearchAndSub    proc    near
  125.         call    BinSearch
  126.         call    AfterSearch
  127.         ret
  128. SearchAndSub    endp
  129.  
  130.  
  131.  
  132. BinSearch    proc    near
  133.         push    bx
  134.         mov    bx,cx            ; compute power of 2
  135.         mov    cx,4            ;   table size
  136.   BinLenLoop:
  137.         shl    cx,1
  138.         cmp    cx,bx
  139.         jb    BinLenLoop
  140.  
  141.         mov    bx,cx            ; start binary search
  142.   BinLess:
  143.         sub    bx,cx
  144.   BinGreater:
  145.         shr    cx,1
  146.         cmp    cx,4
  147.         jb    BinDone         ; no match return
  148.  
  149.         add    bx,cx
  150.         cmp    dx,2[si+bx]
  151.   BinEval:
  152.         ja    BinGreater
  153.         jb    BinLess
  154.  
  155.         cmp    ax,[si+bx]
  156.         ja    BinGreater
  157.         jb    BinLess
  158.   BinDone:
  159.         mov    cx,bx            ; save table index
  160.         lea    si,[si+bx]        ;   and table entry address
  161.         pop    bx
  162.         ret
  163. BinSearch    endp
  164.  
  165.  
  166.  
  167. AfterSearch    proc    near
  168.         sub    ax,[si]         ; subtract seconds
  169.         sbb    dx,2[si]        ;   by table value
  170.         shr    cx,1            ; calculate table index
  171.         shr    cx,1
  172.         ret
  173. AfterSearch    endp
  174.  
  175.  
  176.  
  177. ;************************************************************************
  178. ;*        DateTimeCalc
  179. ;************************************************************************
  180.  
  181. DateTimeCalc    proc    near
  182.         mov    ax,bx
  183.         mov    dx,cx
  184.         push    si
  185.         push    ax            ; save seconds since
  186.         push    dx            ;   year 1900
  187.  
  188.         mov    si,offset Ytab
  189.         mov    cx,4*64
  190.         call    SearchAndSub        ; find and subtract years
  191.         add    cx,1964
  192.         mov    cYear,cx        ; set year
  193.  
  194.         push    ax            ; reminder still too big
  195.         push    dx            ;   for 16 bits,
  196.         shr    dx,1            ;   have to
  197.         rcr    ax,1            ;   divide by 2
  198.         div    m12hour
  199.         inc    ax
  200.         mov    cDayOfYear,ax        ; set day within year
  201.  
  202.         pop    dx            ; restore seconds within year
  203.         pop    ax
  204.  
  205.         and    cl,011b         ; extract leap year index
  206.         mov    cNonLeapYear,cl
  207.         mov    si,offset Motab
  208.         jnz    NoLeapYear
  209.         mov    si,offset Mltab
  210.   NoLeapYear:
  211.         mov    cx,4*16
  212.         call    SearchAndSub        ; find and subtract month
  213.         inc    cx
  214.         mov    cMonth,cx        ; set month within year
  215.  
  216.         shr    dx,1            ; reminder still too big
  217.         rcr    ax,1            ;   for 16 bits, have to
  218.         rcr    bx,1            ;   divide by 2
  219.         div    m12hour         ; divide by 24hr/2
  220.         inc    ax
  221.         mov    cDay,ax         ; set day within month
  222.  
  223.         mov    ax,dx
  224.         xor    dx,dx
  225.         shl    bx,1            ; recover lost bit
  226.         rcl    ax,1            ;   into reminder
  227.         rcl    dx,1
  228.         div    mhour            ; divide by 3600
  229.         mov    cHour,ax        ; set hour within day
  230.  
  231.         mov    ax,dx
  232.         div    m60b            ; divide by 60
  233.         mov    dl,ah
  234.         xor    dh,dh
  235.         mov    cSecond,dx        ; set second within minute
  236.         xor    ah,ah
  237.         mov    cMinute,ax        ; set minute within hour
  238.  
  239.         pop    dx            ; restore seconds since
  240.         pop    ax            ;   year 1900
  241.         shr    dx,1            ; too big for 16 bits...
  242.         rcr    ax,1
  243.         div    m12hour         ; calculate days since 1900
  244.         inc    ax
  245.         xor    dx,dx            ; calculate weeks since 1900
  246.         div    m7
  247.         mov    cWday,dx        ; set weekday
  248.         pop    si
  249.         ret
  250. DateTimeCalc    endp
  251.  
  252.  
  253.  
  254. ;************************************************************************
  255. ;*        SetTime
  256. ;************************************************************************
  257.  
  258. SetTime     proc    near
  259.         push    cs
  260.         push    cs
  261.         pop    ds
  262.         pop    es
  263.         cld
  264.                         ; convert from network byte
  265.         mov    cx,cTime        ;   order
  266.         xchg    ch,cl
  267.         mov    bx,cTime+2
  268.         xchg    bh,bl
  269.  
  270.         mov    dx,tzoffset+2        ;   and apply time zone
  271.         xchg    dh,dl
  272.         sub    bx,dx
  273.         mov    ax,tzoffset        ;   offset
  274.         xchg    ah,al
  275.         sbb    cx,ax
  276.  
  277.         mov    ax,AlterTime        ; add alter-days
  278.         imul    m6hour
  279.         shl    ax,1
  280.         rcl    dx,1
  281.         shl    ax,1
  282.         rcl    dx,1
  283.         add    bx,ax
  284.         adc    cx,dx
  285.  
  286.         mov    ax,AlterTime+2        ; add alter-time
  287.         mov    dx,AlterTime+4
  288.         add    bx,ax
  289.         adc    cx,dx
  290.  
  291.         mov    si,AlgPtr
  292.         or    si,si            ; any daylight algorithm?
  293.         jnz    DoDls
  294.         jmp    SetNoDls
  295.   DoDls:
  296.         push    bx
  297.         push    cx
  298.         add    si,4
  299.         lodsw                ; from switching time
  300.         imul    m1
  301.         sub    bx,ax
  302.         sbb    cx,dx
  303.  
  304.         call    DateTimeCalc        ; dst start evaluation
  305.  
  306.         cmp    si,offset AlgTab.Apa0    ; four entry part?
  307.         jl    SingleEntry
  308.  
  309.         mov    al,AlgEntryLen
  310.         mul    cNonLeapYear
  311.         add    si,ax
  312.         cmp    si,offset AlgTab.Ais0    ; acyclic entry?
  313.         jb    SingleEntry
  314.  
  315.         cmp    cYear,WARNYEAR
  316.         jb    SingleEntry
  317.  
  318.         mov    MsgTermStop,' '        ; activate warning msg
  319.   SingleEntry:
  320.         mov    bp,cDayOfYear
  321.         lodsw                ; from switching weekday
  322.         cmp    al,SAT
  323.         ja    FromDate
  324.         dec    bp
  325.         cmp    ax,cWday
  326.         jg    CurWeekF
  327.         add    bp,7
  328.   CurWeekF:
  329.         sub    bp,cWday
  330.         add    bp,ax
  331.   FromDate:
  332.         pop    cx
  333.         pop    bx
  334.         push    bx
  335.         push    cx
  336.         lodsw                ; from switching week
  337.  
  338.         push    ax
  339.         lodsw                ; until switching time
  340.         imul    m1
  341.         sub    bx,ax
  342.         sbb    cx,dx
  343.  
  344.         call    DateTimeCalc        ; dst end evaluation
  345.  
  346.         mov    di,cDayOfYear
  347.         pop    dx
  348.  
  349.         lodsw                ; until switching weekday
  350.         cmp    al,SAT
  351.         ja    UntilDate
  352.         dec    di
  353.         cmp    ax,cWday
  354.         jg    CurWeekU
  355.         add    di,7
  356.   CurWeekU:
  357.         sub    di,cWday
  358.         add    di,ax
  359.   UntilDate:
  360.         lodsw                ; until switching week
  361.         test    cNonLeapYear,011b
  362.         jnz    SetNotLeap
  363.         cmp    ax,31+28
  364.         jbe    SetChkLU
  365.         inc    ax
  366.   SetChkLU:
  367.         cmp    dx,31+28
  368.         jbe    SetNotLeap
  369.         inc    dx
  370.   SetNotLeap:
  371.         pop    cx
  372.         pop    bx
  373.         cmp    ax,dx            ; north or south of equator?
  374.         jl    SetSouth
  375.         cmp    dx,bp            ; to do or not to do dls?
  376.         jg    SetNoDls
  377.         jmp    short SetChkUntil
  378.   SetSouth:
  379.         cmp    dx,bp            ; to do or not to do dls?
  380.         jle    DoDLSaving
  381.   SetChkUntil:
  382.         cmp    di,ax
  383.         jge    SetNoDls
  384.   DoDLSaving:
  385.         or    GenFlags,DSTNOW
  386.         lodsw                ; dst advance time
  387.         mov    DstAdvance,ax
  388.         imul    m1
  389.         add    bx,ax
  390.         adc    cx,dx
  391.   SetNoDls:
  392.         call    DateTimeCalc        ; calculate date and time
  393.  
  394.         test    Flagword,DONT_SETTIME    ; did we use alter argument?
  395.         jz    SetPCtime
  396.  
  397.         mov    di,offset msgset
  398.         mov    cx,12
  399.         mov    al,' '
  400.         rep    stosb            ; clear "Clock set to"
  401.         jmp    SkipTimeset
  402.   SetPCtime:
  403.         mov    cx,cYear
  404.         mov    dh,byte ptr cMonth
  405.         mov    dl,byte ptr Cday
  406.         mov    ah,2Bh            ; set date
  407.         int    21h
  408.         or    al,al
  409.         jz    DateOK
  410.         mov    al,5            ; error code 5
  411.         call    Terminate
  412.   DateOK:
  413.         mov    ch,byte ptr cHour
  414.         mov    cl,byte ptr cMinute
  415.         mov    dh,byte ptr cSecond
  416.         mov    dl,99
  417.         mov    ah,2Dh            ; set time
  418.         int    21h
  419.         or    al,al
  420.         jz    TimeOK
  421.         mov    al,6            ; error code 6
  422.         call    Terminate
  423.   TimeOK:
  424.   SkipTimeset:                    ; edit time display msg
  425.         mov    al,byte ptr cWday
  426.         mul    m6
  427.         add    ax,offset Weekdays
  428.         mov    si,ax
  429.         mov    di,offset msgweek
  430.         mov    cx,3
  431.         rep    movsw            ; copy weekday string
  432.             
  433.         mov    si,offset cYear
  434.         mov    di,offset msgyear
  435.         mov    ch,'-'
  436.         mov    cl,3
  437.         call    PutNums         ; put date
  438.  
  439.         mov    di,offset msghour
  440.         mov    ch,':'
  441.         mov    cl,3
  442.         call    PutNums         ; put time
  443.  
  444.         mov    si,offset RespondingIpNr
  445.         mov    di,offset msgts
  446.         call    PutIpNum        ; put time server IP #
  447.  
  448.         mov    dx,offset msgset
  449.         mov    ah,9
  450.         int    21h            ; display string
  451.  
  452.         ret
  453. SetTime     endp
  454.  
  455.  
  456.  
  457. ;**********************************************************************
  458. ;
  459. ;    Timezone environment handling
  460. ;
  461. ;**********************************************************************
  462.  
  463.         assume    ds:code_s
  464.  
  465. comment |
  466. ==========
  467. tech.notes/pc.code #29, from pmaupin, 3407 chars, Sat Jun  4 22:40:45 1988
  468. ----------
  469. TITLE: Finding DOS's master environment pointer
  470. This is a fragment of code that my SD.COM program uses to find
  471. the environment.  This fragment is different than most ways of
  472. finding the environment, in that it finds the MASTER environment block,
  473. not the current process's parent's environment.
  474.  
  475. This is useful in some cases, and has the added advantage that
  476. it does NOT behave differently when executing under CodeView,
  477. so you do NOT have to hard-code your system's DOS environment address
  478. into your program in order to debug it.
  479.     |
  480.  
  481. EnvPtr           EQU         2CH       ; Offset in PSP
  482.  
  483. CommandInterrupt   EQU         2EH       ; entry point into first Command.Com
  484.                        ; through interpreter
  485.  
  486. DosSegPtr       EQU         CommandInterrupt * 4 + 2
  487.  
  488.  
  489. ; FindEnvironment is passed:
  490.  
  491. ;   DS should point to program PSP
  492.  
  493. ; FindEnvironment returns:
  494.  
  495. ;   ES points to master environment block, or program's copy if couldn't
  496. ;           find the master.
  497.  
  498. ;   CX is length of block, or 0 if couldn't find the master.
  499.  
  500. ; FindEnvironment destroys:
  501.  
  502. ;   AX, SI
  503.  
  504.  
  505. FindEnvironment    PROC  NEAR
  506.            xor     si,si              ; Point to segment 0
  507.            mov     es,si
  508.            mov     si, word ptr es:[DosSegPtr]
  509.            mov     ax,si
  510.            call  VerifyBlock          ; make sure we've found COMMAND
  511.            jnz     GotBlock          ; jump if not a good block --
  512.                           ; use process's environment
  513.  
  514.            mov     ax,es:[EnvPtr+10h]   ; get COMMAND's environment ptr
  515.            or     ax,ax              ; jump if COMMAND has a
  516.            jnz     MaybeGoodBlock       ; subsidiary environment
  517.  
  518.            mov     ax,si              ; If no subsidiary, just use
  519.            add     ax,cx              ; the allocation block
  520.            inc     ax              ; immediately after COMMAND
  521.  
  522. MaybeGoodBlock:    call  VerifyBlock          ; verify that we have a good
  523.                           ; one, one way or another
  524. GotBlock:
  525.            shl     cx,1              ; multiply by 16 to get
  526.            shl     cx,1              ; length in bytes
  527.            shl     cx,1
  528.            shl     cx,1
  529.            mov     es,ax
  530.            ret
  531.  
  532.  
  533. ; VerifyBlock tries to insure that we're pointing to a valid DOS
  534. ; allocation block.  If not, returns the current process's environment
  535. ; block.
  536.  
  537.  
  538. VerifyBlock       PROC  NEAR
  539.            dec     ax             ; get block header into ES
  540.            mov     es,ax
  541.            inc     ax
  542.  
  543.            cmp     byte ptr es:[0],04Dh     ; make sure signature is valid
  544.            jnz     UseCurrent
  545.            cmp     word ptr es:[1],si     ; make sure owner is valid
  546.            jnz     UseCurrent
  547.            mov     cx, word ptr es:[3]     ; retrieve the length
  548.            ret
  549.  
  550. UseCurrent:       mov     ax,word ptr ds:[EnvPtr] ; get current process's env
  551.            xor     cx,cx             ; zero length
  552.            ret
  553. VerifyBlock       ENDP
  554.  
  555. FindEnvironment    ENDP
  556.  
  557. comment |
  558. So far, this seems to work.  I would welcome any feedback on its
  559. efficacy, but if the feedback is negative, please give the DOS version
  560. and a detailed problem description.  Thanks,
  561. Pat
  562.     |
  563.  
  564. ZoneMsg         db      CR, LF, "Environment variable "
  565. ZoneString      db      "TZ=+0100",0,0,"$                      "
  566. ZONESPACE    equ    $-ZoneString
  567. ZoneVarLen    dw    3
  568. ZoneStrLen    dw    10
  569. ZoneDstInd    dw    10
  570.  
  571. ;************************************************************************
  572. ;*        SetZone
  573. ;*
  574. ;************************************************************************
  575.  
  576.         assume    ds:code_s
  577.  
  578. SetZone     proc    near
  579.         test    GenFlags,ARGZONE    ; anything to SET?
  580.         jnz    SetZoneInfo
  581.         ret
  582.  
  583.   SetZoneInfo:
  584.         cld
  585.         test    GenFlags,ARGZONESPEC    ; extended syntax?
  586.         jnz    SetZoneSpecial
  587.  
  588.         mov    ax,DstAdvance        ; -no, use numeric zones
  589.         xor    dx,dx            ; compute current time offset
  590.         mov    cx,tzoffset
  591.         xchg    ch,cl
  592.         mov    bx,tzoffset+2
  593.         xchg    bh,bl
  594.         sub    ax,bx
  595.         sbb    dx,cx
  596.         mov    cl,'+'
  597.         jns    ZonePositive        ; current time offset sign?
  598.         mov    cl,'-'
  599.         call    NegDxAx
  600.   ZonePositive:
  601.         mov    di, offset ZoneString
  602.         add    di,ZoneVarLen
  603.         mov    [di],cl
  604.         div    mhour            ; compute hours
  605.         push    ax
  606.         mov    ax,dx
  607.         div    m60b            ;   and minutes
  608.         xor    ah,ah
  609.         mov    di,offset ZoneString+3
  610.         add    di,ZoneVarLen
  611.         mov    PutMinDigits,2    ; *test
  612.         call    PutNum            ; put minutes
  613.         pop    ax
  614.         sub    di,4
  615.         call    PutNum            ; put hours
  616.         jmp    short EnvMaster
  617.  
  618.   SetZoneSpecial:
  619.         test    GenFlags,DSTNOW     ; is it normal or dls time?
  620.         jz    EnvMaster
  621.         mov    di,offset ZoneString    ; -dls, copy dls name
  622.         mov    si,di            ;      on top of normal name
  623.         add    di,ZoneVarLen
  624.         add    si,ZoneDstInd
  625.   SetZoneLoop:
  626.         lodsb
  627.         stosb
  628.         cmp    al,0
  629.         jne    SetZoneLoop
  630.         stosb
  631.         mov    al,'$'
  632.         stosb
  633.         sub    di,offset ZoneString+1
  634.         mov    ZoneStrLen,di
  635.   EnvMaster:
  636.         call    FindEnvironment     ; Find master environment
  637.  
  638.         xor    di,di
  639.         xor    al,al
  640.   EnvNext:
  641.         jcxz    EnvNotFound
  642.  
  643.         test    FlagWord,DONT_SETTIME
  644.         jnz    EnvZonePr
  645.         push    cx            ; look for TZ=
  646.         push    di
  647.         mov    cx,ZoneVarLen
  648.         mov    si,offset ZoneString
  649.         repe    cmpsb
  650.         jnz    EnvNoMatch
  651.  
  652.         pop    di            ; if found, remove whole string
  653.         pop    cx
  654.         push    cx
  655.         push    di
  656.         repne    scasb
  657.         mov    si,di
  658.         pop    di
  659.         push    di
  660.         push    es
  661.         pop    ds
  662.         rep    movsb
  663.         push    cs
  664.         pop    ds
  665.   EnvNoMatch:
  666.         pop    di
  667.         pop    cx
  668.  
  669.         cmp    byte ptr es:[di],0    ; end of strings?
  670.         je    EnvEnd
  671.         repne    scasb            ; -no, skip past this string
  672.         jmp    short EnvNext
  673.   EnvEnd:
  674.         cmp    cx,ZoneStrLen        ; add TZ string to the end
  675.         jb    EnvNotFound
  676.         mov    cx,ZoneStrLen
  677.         mov    si,offset ZoneString
  678.         rep    movsb
  679.  
  680.   EnvZonePr:
  681.         mov    dx,offset ZoneMsg
  682.         push    cs
  683.         pop    ds
  684.         mov    ah,9
  685.         int    21h            ; display env var contents
  686.  
  687.   EnvNotFound:
  688.         push    cs            ; restore ds and es
  689.         push    cs
  690.         pop    ds
  691.         pop    es
  692.         ret
  693. SetZone     endp
  694.