utcal


* Calendar sub routine
*
* Released under the GNU GENERAL PUBLIC LICENSE, Version 2, June 1991
*
* Functional code by Laurence Reeves 1994(?)+
*
* Re-packaged by pjwitte 2oo6
*
* V0.01 September 27th 2006
*

        section code

        xdef ut_cal

dot     equ     1961    (n.b. dot+3 is a leap year)

*
ut_cal
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Convert date in seconds (offset from 1961 Jan 01 00:00:00) into
*         year, month, day, weekday, hours, minutes, seconds
*
* Entry: d1.l = time in seconds since 00:00:00 on 1st jan in year dot
* Exit : d4.w = day of week (0..6) / month (0..11)
*        d1.w = day of month (1..31)
*        d6.l = hrs.w  / year.w
*        d3.l = secs.w / mins.w

        moveq   #60,d2          long dividing by 60
        bsr.s   longd           d1 = mins since t0; d0 = secs remain
        swap    d3              d3 msw = secs / lsw will get mins
        bsr.s   longd           d1 = hrs since t0; d0 = mins remaining
        divu    #24,d1          d1 = hrs remaining / days since t0
        move.l  d1,d6           d6 msw = hrs
        moveq   #0,d4
        move.w  d1,d4
        move.l  d4,d1           duplicate with msw clear
        divu    #7,d4           d4 msw = day of week
        divu    #3*365+366,d1   d1 = days remaining / fyps since t0
        move.w  d1,d6           d6 lsw = sets of four years since dot
        clr.w   d1
        swap    d1              d1 = day of four year period
        divu    #365,d1         d1 = day of year / year of fyp
        moveq   #31+28,d2       d2 = jan+feb (non-leap)
        subq.w  #3,d1           check for year in period >= 3
        blt.s   notleap
        beq.s   not4th          if it's the final odd day 0 / year 4
        move.l  #365<<16,d1     make it right
not4th
        moveq   #31+29,d2       d2 = jan+feb(leap)
notleap
        asl.w   #2,d6
        add.w   d1,d6
        add.w   #dot+3,d6       d6 lsw = year
        clr.w   d1
        swap    d1              d1 = day in year
        sub.w   d2,d1
        blt.s   notjf           if day >= jan+feb (month >= march) then
        moveq   #31+30,d2       make feb look like a 30 day month
notjf
        add.w   d2,d1

* Pattern now goes like: 31,30,31,30,31,30,31,31,30,31,30,31
        moveq   #7,d2           d2 = months in cycle
        mulu    d2,d1
        addq.w  #3,d1
        divu    #7*30+4,d1      d1 = (day * d5 + d5 div 2) / (days in cycle)
        move.w  d1,d4           d4 lsw = month in year (quotient)
        clr.w   d1
        swap    d1
        divu    d2,d1           day in month = remainder div d5
        addq.w  #1,d1           plus one
        rts

* Long division subroutine
* Entry: d1.l = dividend
*        d2.w = divisor
* Exit : d3.w = remainder
*        d1.l = d0.l = quotient

longd
        moveq   #0,d0           clear d0
        swap    d1              get msw of dividend
        move.w  d1,d0           in d0
        divu    d2,d0           divide it by divisor
        swap    d0              put remainder
        move.w  d0,d1           back in number
        swap    d1
        divu    d2,d1           divide this by divisor
        move.w  d1,d0           put lsw of dividend into d0
        swap    d1              get remainder
        move.w  d1,d3           to d3.w
        move.l  d0,d1           duplicate quotient
        rts

        end

Back to Index
HTML generated by the amazing asm2htm !
2006 Oct 01 00:36:27