; Calculating the day of the week for a given date ; ================================================ ; mdfs.net/Info/Comp/PDP11/ProgTips/Date/DayOfWeek - J.G.Harston ; ; Based on code at http://6502.org/source/misc/dow.htm by Paul Guertin. ; ; This routine works for any date from 1900-01-01 to 2199-12-31. ; No range checking is done, so validate input before calling. ; ; It uses the formula ; Weekday = (day + offset[month] + year + year/4 + fudge) mod 7 ; offset[month] adjusts the day count so 1st of a month is effectively ; the (lastday+1)-th of the previous month. ; fudge is -1 after 2099 as 2100 is not a leap year. ; ; On entry r0=day, 1..31 ; r1=month, 1..12 ; r2=year-1900, 0..255 ; On exit r0=day of week 0..6 for Sun..Sat ; Needs incrementing with INC R0 after calling to become ; standard 1..7 range ; Size 56 bytes ; org &8000 .DayOfWeek cmp r1,#3 ; Year starts in March to make leap day the last sbc r2 ; If Jan or Feb, decrement year bpl dowMarch ; Not gone negative, not 1900 mov #6,r2 ; 1900 is not a leap year, adjust base .dowMarch cmp #2099-1900,r2 sbc r0 ; 2100 is not a leap year, so reduce day count if after 2099 movb dowMonths-1(r1),r1 ; R1=offset[month] (nb, not position-independent instruction) add r1,r0 ; R0=day+offset[month] add r2,r0 ; R0=day+offset[month]+year asr r2 asr r2 ; R2=year DIV 4 add r2,r0 ; R0=day+offset[month]+year+(year DIV 4) .dowMod7 sub #7,r0 bcc dowMod7 ; Reduce R0 to R0 MOD 7 add #7,r0 ; Balance final sub #7, replace with add #8,r0 to return 1-7 rts pc .dowMonths equb 1,4,3,6,1,4,6,2,5,0,3,5 ; Month offsets ; ; You can test this with: ; ; FOR C%=1 TO 255 ; FOR B%=1 TO 12 ; FOR A%=1 TO 31 ; PRINT A%;"/";B%;"/";1900+C%;" "; ; PRINT MID$("SunMonTueWedThuFriSat",((USR DayOfWeek) AND &FF)*3+1,3) ; NEXT A%:NEXT B%:NEXT C% ;