\ Calculating the day of the week for a given date
\ ================================================
\ Based on code at http://6502.org/source/misc/dow.htm by Paul Guertin.
\
\ This routine works for any date from 1900-03-01 to 2155-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 when after 2099 as 2100 is not a leap year.
\
\ On entry A=day, 1..31
\ X=month, 1..12
\ Y=year-1900, 0..255
\ On exit A=day of week 0..6 for Sun..Sat, Carry will be Set
\ Needs incrementing with ADC #0 after calling to
\ become standard 1..7 range
\ Size 45 bytes + 1 byte workspace
\
.DayOfWeek
CPX #3:BCS dow_march :\ Year starts in March to bypass leap year problem
DEY :\ If Jan or Feb, decrement year
.dow_march
EOR #&7F :\ Invert A so carry works right
CPY #200 :\ Carry will be 1 if 22nd century
ADC dow_months-1,X :\ A=day+month_offset
STA dow_tmp
TYA:JSR dow_mod7 :\ Get the year MOD 7 to prevent overflow
SBC dow_tmp:STA dow_tmp :\ A=day+month_offset+year
TYA:LSR A:LSR A :\ Get the year DIV 4
CLC:ADC dow_tmp :\ A=day+month_offset+year+year/4, fall through to MOD 7
.dow_mod7
ADC #7:BCC dow_mod7 :\ Reduce A to A MOD 7
RTS
.dow_months
EQUB 1:EQUB 5:EQUB 6:EQUB 3 :\ Month offsets
EQUB 1:EQUB 5:EQUB 3:EQUB 0
EQUB 4:EQUB 2:EQUB 6:EQUB 4
.dow_tmp
EQUB 0 :\ Temporary storage
\
\
\ You can test this with:
\
\ FOR Y%=1 TO 255
\ FOR X%=1 TO 12
\ FOR A%=1 TO 31
\ PRINT A%;"/";X%;"/";1900+Y%;" ";
\ PRINT MID$("SunMonTueWedThuFriSat",((USRDayOfWeek) AND &FF)*3+1,3)
\ NEXT A%:NEXT X%:NEXT Y%
\
\ I must say that this is an impressive bit of code!
\