; =============================================================================
;
; Litos - Calendar, date and time
;
; =============================================================================
; Julian date: days from 1/1/4713 BCE noon 12:00 (it was Monday)
; Julian date has period 7980 years, than start year 1 again.
; Julian date range: 1/1/4713 BCE 12:00 to 1/1/3268 CE 12:00, e.g. 0 to 2914673
; days. Julian period is 2518277472000000000 100-nanoseconds (e.g. 7980 years).
;
; Julian calendar: till Thursday 10/4/1582 (begins julian date 2299159.5)
; Gregorian calendar: from Friday 10/15/1582 (begins julian date 2299160.5)
; 1/1/1 CE: JD=1721423.5, Saturday (there is no year 0!)
; 1/1/1 BCE: JD=1721057.5 Thursday
; Julian year: 365.25 days, Gregorian year: 365.2425 days.
;
; ISO-8601: date format YYYY-WW-DD (year-week-day_of_week). Week: 1 to 53,
; day of week: 1 to 7, 1=Monday. First week of year is such a week, which
; contains first Thursday of Gregorian year, and week containing January 4th.
;
; Normal year, 365 days:
; Mo Tu We Th Fr Sa Su
; 1 no 1 + 51*7 + 7 yes, 52, 4.1. is Th
; 1 2 no 2 + 51*7 + 6 yes, 52, 4.1. is We
; 1 2 3 no 3 + 51*7 + 5 yes, 52, 4.1. is Tu
; 1 2 3 4 yes 4 + 51*7 + 4 yes, 53, 4.1. is Mo
; 1 2 3 4 5 yes 5 + 51*7 + 3 no, 52, 4.1. is Su
; 1 2 3 4 5 6 yes 6 + 51*7 + 2 no, 52, 4.1. is Sa
; 1 2 3 4 5 6 7 yes 7 + 51*7 + 1 no, 52, 4.1. is Fr
;
; Leap year, 366 days:
; Mo Tu We Th Fr Sa Su
; 1 no 1 + 52*7 + 1 no, 52, 4.1. is Fr
; 1 2 no 2 + 51*7 + 7 yes, 52, 4.1. is Th
; 1 2 3 no 3 + 51*7 + 6 yes, 52, 4.1. is We
; 1 2 3 4 yes 4 + 51*7 + 5 yes, 53, 4.1. is Tu
; 1 2 3 4 5 yes 5 + 51*7 + 4 yes, 53, 4.1. is Mo
; 1 2 3 4 5 6 yes 6 + 51*7 + 3 no, 52, 4.1. is Su
; 1 2 3 4 5 6 7 yes 7 + 51*7 + 2 no, 52, 4.1. is Fr
;
; Year 1582 has 355 days (it is not leap), 51 weeks.
; =============================================================================
CODE_SECTION 32
; -----------------------------------------------------------------------------
; Convert system time to Julian time
; -----------------------------------------------------------------------------
; INPUT: EBX = system time structure (see SYSTIME: only time and date
; entries are used. Flags, week, day in year and day
; of week are ignored)
; OUTPUT: EDX:EAX = Julian time (100-nanosec from 1/1/4713 BCE 12:00)
; Value is in range from 0 to 2518277471999999999.
; NOTES: Entries are taken as signed and their overlaps are accounted.
; Takes 150 ns on 1.6 GHz CPU.
; -----------------------------------------------------------------------------
; On whole function: ESI = system time structure, EBP:EDI = accumulator.
; ------------- Push registers
SystemToJulian: push ebx ; push EBX
push ecx ; push ECX
push esi ; push ESI
push edi ; push EDI
push ebp ; push EBP
mov esi,ebx ; ESI <- system time structure
; ------------- Sum seconds and 100-nanoseconds (-> EBP:EDI)
movsx eax,byte [esi+SYSTIME_Sec] ; EAX <- seconds
mov ecx,10000000 ; ECX <- 100-nanoseconds per second
imul ecx ; EAX <- recalc seconds to 100-nanosec
add eax,[esi+SYSTIME_100NSec] ; add 100-nanoseconds
adc edx,byte 0 ; overflow
xchg eax,edi ; EDI <- accumulator LOW
mov ebp,edx ; EBP <- accumulator HIGH
; ------------- Sum hours and minutes (add to EBP:EDI)
movsx eax,byte [esi+SYSTIME_Hour] ; EAX <- hours
sub eax,byte 12 ; time correction
xor ecx,ecx ; ECX <- 0
mov cl,60 ; ECX <- 60, minutes per hour
imul ecx ; EAX <- minutes
movsx ecx,byte [esi+SYSTIME_Min] ; ECX <- minutes
add eax,ecx ; EAX <- hours + minutes
mov ecx,60*10000000 ; ECX <- 100-nanoseconds per minute
imul ecx ; recalc minutes to 100-nanoseconds
add edi,eax ; add minutes to accumulator LOW
adc ebp,edx ; add minutes to accumulator HIGH
; ------------- Carry month (-> EAX) to year (-> ECX)
movsx eax,byte [esi+SYSTIME_Month] ; EAX <- month
dec eax ; EAX <- change month to zero based
movsx ecx,word [esi+SYSTIME_Year] ; EBX <- year
SystemToJulian1:cmp eax,byte 12 ; is it valid value?
jb SystemToJulian3 ; it is valid value
or eax,eax ; is month negative?
jns SystemToJulian2 ; month is not negative
add eax,byte 12 ; correct month
dec ecx ; correct year
jmp short SystemToJulian1 ; next year
SystemToJulian2:sub eax,byte 12 ; correct month
inc ecx ; correct year
jmp short SystemToJulian1 ; next year
; ------------- Preset leap year flag (if year is divided by 4)
SystemToJulian3:push eax ; push month (zero based)
mov bl,0 ; BL <- 0, preset flag, no leap year
test cl,3 ; is it leap year?
jnz SystemToJulia32 ; it is not leap year
inc ebx ; BL <- 1, flag, it is leap year
; ------------- Check if it is Gregorian calendar (1600 and more)
SystemToJulia32:sub ecx,1600 ; is it Gregorian calendar?
js SystemToJulian6 ; it is (mostly) Julian calendar
cmp ecx,3268-1600 ; maximal year
jb SystemToJulian4 ; year is OK
mov ecx,3268-1600 ; limit year
; ------------- Get century (offset from 16th century)
SystemToJulian4:mov eax,ecx ; EAX <- year
mov bh,100 ; BH <- 100, years per century
div bh ; AL <- century, AH <- year in century
; ------------- Correct leap flag (century is leap if it is divided by 4)
or ah,ah ; is it century?
jnz SystemToJulia42 ; it is not century
test al,3 ; is century divided by 4?
jz SystemToJulia42 ; century is divided by 4, leap year
mov bl,0 ; BL <- 0, flag, not leap year
; ------------- Recalc year to days with Gregorian calendar
SystemToJulia42:mov bh,ah ; BH <- year in century
movzx ecx,al ; ECX <- century - 16
mov eax,365 ; EAX <- days in normal year
movzx edx,bh ; EDX <- year in century
mul edx ; EAX <- days for normal years
add eax,[Days1600+ecx*4] ; add days from 1/1/1600
add eax,2305448+10 ; add days for 1/1/1600 + 10
test cl,3 ; is century leap?
movzx ecx,bh ; ECX <- year in century
jz SystemToJulia64 ; century is leap
cmp ecx,byte 3 ; is it first quadrennium?
jle SystemToJulia66 ; it is first quadrennium
dec ecx ; withou first (not leap) year
jmp short SystemToJulia65
; ------------- Recalc year to days with Julian calendar (or part of Gregorian)
SystemToJulian6:add ecx,4712+1600 ; change year to zero based
jns SystemToJulia62 ; year is OK
xor ecx,ecx ; ECX <- 0, limit minimal year
SystemToJulia62:mov eax,365 ; EAX <- days to normal year
mul ecx ; EAX <- days for normal years
SystemToJulia64:add ecx,byte 3 ; round up
SystemToJulia65:shr ecx,2 ; ECX <- number of leap years
add eax,ecx ; add leap days
SystemToJulia66:pop edx ; EDX <- pop month (zero based)
; ------------- Add days in months
or bl,bl ; is leap year?
mov ebx,DayYearTabN ; EBX <- table for normal year
jz SystemToJulian7 ; it is normal year
mov ebx,DayYearTabL ; EBX <- table for leap year
SystemToJulian7:movzx ecx,word [ebx+edx*2] ; ECX <- days for months
add eax,ecx ; add days for months
; ------------- Add days in month
movsx ecx,byte [esi+SYSTIME_Day] ; ECX <- day in month
dec ecx ; day correction
add eax,ecx ; add days to current date
jns SystemToJulian8 ; date is OK
xor eax,eax ; EAX <- 0, minimal date
; ------------- Correction for date 11/1/1582 and more
SystemToJulian8:cmp eax,2299171 ; is it 10/15/1582 or more?
jb SystemToJulia82 ; it is lower date
sub eax,byte 10 ; date correction
SystemToJulia82:cmp eax,2914673 ; maximal date
jbe SystemToJulia84 ; date is OK
mov eax,2914673 ; limit maximal date
; ------------- Recalc days to minutes
SystemToJulia84:mov ecx,24*60 ; ECX <- minutes per day
imul ecx ; recalc days to minutes
; ------------- Recalc minutes to 100-nanoseconds
xchg eax,ebx ; EBX <- store minutes LOW
xchg eax,edx ; EAX <- minutes HIGH
mov ecx,60*10000000 ; ECX <- 100-nanoseconds per minute
mul ecx ; recalc minutes HIGH to 100-nanosec
add ebp,eax ; add minutes HIGH to accumulator HIGH
xchg eax,ebx ; EAX <- minutes LOW
mul ecx ; recalc minutes LOW to 100-nanosec
add eax,edi ; add accumulator LOW to minutes LOW
adc edx,ebp ; add accumulator HIGH to minutes LOW
; ------------- Limit result (maximal allowed value 2518277472000000000-1)
jns SystemToJulian9 ; value is not negative
xor eax,eax ; EAX <- 0, minimal value LOW
xor edx,edx ; EDX <- 0, minimal value HIGH
SystemToJulian9:cmp edx,22f2b804h ; check maximum HIGH
jne SystemToJulia92
cmp eax,0b46dbfffh ; check maximum LOW
SystemToJulia92:jbe SystemToJulia94 ; date is OK
mov edx,22f2b804h ; limit value HIGH
mov eax,0b46dbfffh ; limit value LOW
; ------------- Pop registers
SystemToJulia94:pop ebp ; pop EBP
pop edi ; pop EDI
pop esi ; pop ESI
pop ecx ; pop ECX
pop ebx ; pop EBX
ret
; -----------------------------------------------------------------------------
; Convert Julian time to system time
; -----------------------------------------------------------------------------
; INPUT: EDX:EAX = Julian time (100-nanosec from 1/1/4713 BCE, noon)
; must be in range from 0 to 2518277471999999999
; EBX = system time structure (see SYSTIME)
; OUTPUT: EBX structure filled with system time (only if NC)
; CY = invalid range of Julian time, structure not filled
; NOTES: Takes 800 ns on 1.6 GHz CPU.
; -----------------------------------------------------------------------------
; On whole function: ESI = system time structure
; ------------- Push registers
JulianToSystem: push eax ; push EAX
push ebx ; push EBX
push ecx ; push ECX
push edx ; push EDX
push esi ; push ESI
mov esi,ebx ; ESI <- system time structure
; ------------- Check valid range (invalid value 2518277472000000000 and more)
cmp edx,22f2b804h ; check maximum HIGH
jne JulianToSystem1
cmp eax,0b46dc000h ; check maximum LOW
JulianToSystem1:cmc ; invert CF
jc near JulianToSystem9 ; invalid Julian time
; ------------- Split to minutes (-> EBX) and 100-nanoseconds (-> EDX)
mov ecx,60*10000000 ; ECX <- 100-nanoseconds per minute
div ecx ; split to minutes and 100-nanoseconds
xchg eax,ebx ; EBX <- minutes (0 to 4197129119)
; ------------- Get number of 100-nanoseconds and number of seconds
xor eax,eax ; EAX <- 0
mov [esi+SYSTIME_Flags],al ; clear flags
xchg eax,edx ; EAX <- 100-nanoseconds, EDX <- 0
mov ecx,10000000 ; ECX <- 100-nanoseconds per second
div ecx ; get 100-nanoseconds and seconds
mov [esi+SYSTIME_100NSec],edx ; store 100-nanoseconds
mov [esi+SYSTIME_Sec],al ; store second
; ------------- Split to minutes (-> EAX) and days (-> EDX, 0 to 2914672)
xchg eax,ebx ; EAX <- minutes
xor edx,edx ; EDX <- 0
mov ecx,24*60 ; ECX <- minutes per day
div ecx ; get minutes and days
xchg eax,edx ; EAX <- minutes, EDX <- days
; ------------- Get minute and hour (-> AL)
mov cl,60 ; CL <- number of minutes per hour
div cl ; get number of minutes and hours
mov [esi+SYSTIME_Min],ah ; store minute
; ------------- Shift day over midnight
add al,12 ; hour correction
cmp al,24 ; is it midnight?
jb JulianToSystem2 ; it is not midnight
sub al,24 ; hour correction
inc edx ; day correction
JulianToSystem2:mov [esi+SYSTIME_Hour],al ; store hour
xchg eax,edx ; EAX <- day
; ------------- Get day of week
xor edx,edx ; EDX <- 0
mov ebx,eax ; EBX <- push current day
inc eax ; day correction
mov cx,7 ; ECX <- 7, number of days in week
div ecx ; get day of week
mov [esi+SYSTIME_DayWeek],dl ; store day of week
; ------------- Check if it is Gregorian calendar (=Julian date 2299160.5+0.5)
xor edx,edx ; EDX <- 0
mov eax,-4712 ; EAX <- preset year correction
xchg eax,ebx ; EAX <- current day, EBX <- -4712
cmp eax,2299160+1 ; is it Gregorian calendar?
jb JulianToSystem5 ; it is Julian calendar
or byte [esi+SYSTIME_Flags],B1 ; flag - Gregorian calendar
; ------------- Years before 1/1/1600
add eax,byte 10 ; date correction
cmp eax,2305447+1+10; is it 1/1/1600 or more?
jb JulianToSystem5 ; calculate date as for Julian
sub eax,2305447+1+10; EAX <- day offset from 1/1/1600
; ------------- Get century (-> EAX, offset in century -> ECX)
mov ecx,eax ; ECX <- day offset from 1/1/1600
shr eax,15 ; ECX <- index in hash table
movzx eax,byte [Days1600Hash+eax] ; ECX <- century
cmp ecx,[Days1600+eax*4-16*4] ; is it correct century?
jae JulianToSystem3 ; century is OK
dec eax ; correct century
JulianToSystem3:sub ecx,[Days1600+eax*4-16*4] ; ECX <- offset in century
; ------------- Recalc century to years (-> BX)
mov ebx,eax ; EBX <- century
mov ah,100 ; AH <- 100, year per century
mul ah ; AX <- years for centuries
xchg eax,ebx ; BX <- years, EAX <- century
; ------------- Get first year in quadrennium (here is EDX = 0)
xchg eax,ecx ; EAX <- days, ECX <- century
test cl,3 ; is it leap century?
jz JulianToSystem5 ; it is leap century
inc eax ; add 1 leap day
mov ecx,3*365 + 366 ; ECX <- days for quadrennium
cmp eax,ecx ; is first quadrennium?
jae JulianToSystem5 ; it is not first quadrennium
dec eax ; return leap day
mov ecx,365 ; ECX <- 365, days in first year
xchg eax,edx ; EDX <- days, EAX <- 0
jmp short JulianToSyst52
; ------------- Get quadrennium for Julian calendar (2299160 -> 1573 rest 1007)
JulianToSystem5:mov ecx,3*365 + 366 ; ECX <- days for quadrennium
div ecx ; calculate quadrennium
shl eax,2 ; EAX <- years for quadrenniums
; ------------- Get years in last quadrennium
mov ecx,366 ; ECX <- 366, days in a year
JulianToSyst52: cmp edx,ecx ; first year
jb JulianToSystem6 ; it is first year
sub edx,ecx ; days in first year
inc eax ; increase year
mov cx,365 ; ECX <- 365, days in a year
cmp edx,ecx ; first year
jb JulianToSystem6 ; it is first year
sub edx,ecx ; days in first year
inc eax ; increase year
cmp edx,ecx ; first year
jb JulianToSystem6 ; it is first year
sub edx,ecx ; days in first year
inc eax ; increase year
JulianToSystem6:add ebx,eax ; EBX <- store year
; ------------- Check leap year for Gregorian calendar
test byte [esi+SYSTIME_Flags],B1 ; is Gregorian calendar?
jz JulianToSyst64 ; it is not Gregorian calendar
mov eax,ebx ; EAX <- year
mov cl,100 ; CL <- 100 years per century
div cl ; get century
or ah,ah ; is it century?
jnz JulianToSyst64 ; it is not century
test al,3 ; is century leap (divided by 4) ?
jnz JulianToSystem7 ; century is not leap
; ------------- Check leap year for Julian calendar (year divided with 4)
JulianToSyst64: test bl,3 ; is year divided with 4?
jnz JulianToSystem7 ; it is not leap year
JulianToSyst66: or byte [esi+SYSTIME_Flags],B0 ; flag - leap year
; ------------- Find month and day
JulianToSystem7:push edx ; push EDX (day in year)
mov ecx,DayYearTabN ; days for normal year
test byte [esi+SYSTIME_Flags],B0 ; is leap year?
jz JulianToSyst72 ; is normal year
mov ecx,DayYearTabL ; days for leap year
JulianToSyst72: mov eax,edx ; EAX <- day in year
shr eax,4 ; EAX <- day in year / 16
movzx eax,byte [DayYearHash+eax] ; EAX <- month (hashed)
cmp dx,[ecx+eax*2-2]; is it correct month?
jae JulianToSyst74 ; month is OK
dec eax ; correct month
JulianToSyst74: sub dx,[ecx+eax*2-2]; DX <- day in month
mov [esi+SYSTIME_Month],al ; store month
inc edx ; DL <- day + 1 correction
mov [esi+SYSTIME_Day],dl ; store day in month
pop edx ; pop EDX (day in year)
; ------------- Correction for 1582 year
cmp bx,1582 ; is it 1582 year?
jne JulianToSystem8 ; no
cmp edx,277 ; is it day 10/15/1582 or more?
jb JulianToSystem8 ; no correction
sub edx,byte 10 ; restore right day number
; ------------- Store day in year
JulianToSystem8:mov [esi+SYSTIME_DayYear],dx ; store day in year
; ------------- Store year
mov [esi+SYSTIME_Year],bx ; store year
; ------------- Prepare day of week of January 4th (-> BH)
movzx eax,byte [esi+SYSTIME_DayWeek] ; EAX <- day of week
sub eax,edx ; EAX <- day of week - day
add eax,3+53*7 ; correction
xor ecx,ecx ; ECX <- 0
mov cl,7 ; CL <- 7, days per week
div cl ; AH <- day of week of January 4th
xchg eax,ebx ; BH <- push day of week of January 4th
; ------------- Prepare number of weeks in this year
mov bl,52 ; 52 weeks
or bh,bh ; is it Sunday?
jz JulianToSyst81 ; this year has 53 weeks
cmp bh,6 ; is it Saturday?
jne JulianToSyst82 ; this year has 52 weeks
test byte [esi+SYSTIME_Flags],B0 ; is it leap year?
jz JulianToSyst82 ; it is not leap year, it has 52 weeks
JulianToSyst81: or byte [esi+SYSTIME_Flags],B2 ; flags of 53 weeks
inc ebx ; BL <- 53 weeks
; ------------- Day offset (from begin of year) of first week (-> EAX)
JulianToSyst82: mov al,4 ; AL <- day correction
sub al,bh ; AL <- day offset of first week
movsx eax,al ; EAX <- day offset of first week
; ------------- Get week (first week is week with January 4th, ISO-8601)
xchg eax,edx ; EAX <- day in year, EDX <- day offset
sub eax,edx ; EAX <- distance from first week
add eax,ecx ; EAX += 7, correction
div cl ; AL <- week
; ------------- Last week of previous year (only for January 1,2,3)
or al,al ; is it last week of previous year?
jnz JulianToSyst84 ; it is not last week
or byte [esi+SYSTIME_Flags],B3 ; set flag of last week
mov cx,[esi+SYSTIME_Year] ; CX <- year
mov al,51 ; week 51 for 1582 year
cmp cx,1583 ; is it 1583 year?
je JulianToSyst84 ; previous year has 51 weeks
inc eax ; AL <- week 52
cmp bh,1 ; is January 4th in Monday?
je JulianToSyst83 ; previous year has 53 weeks
cmp bh,2 ; is January 4th in Tuesday?
jne JulianToSyst84 ; previous year has 52 weeks
dec cx ; CX <- previous year
test cl,3 ; is previous year leap?
jnz JulianToSyst84 ; previous year is not leap, 52 weeks
cmp cx,1700 ; not leap year
je JulianToSyst84 ; it has 52 weeks
cmp cx,2100 ; not leap year
je JulianToSyst84 ; it has 52 weeks
cmp cx,2500 ; not leap year
je JulianToSyst84 ; it has 52 weeks
cmp cx,2900 ; not leap year
je JulianToSyst84 ; it has 52 weeks
JulianToSyst83: inc eax ; AL <- week 53
; ------------- First week of following year (1581 year is always OK)
JulianToSyst84: cmp al,bl ; is it valid week?
jbe JulianToSyst85 ; it is valid week
mov al,1 ; first week of next year
or byte [esi+SYSTIME_Flags],B4 ; first week of next year
; ------------- Store week
JulianToSyst85: mov [esi+SYSTIME_Week],al ; store week
; ------------- Pop registers
clc ; result OK
JulianToSystem9:pop esi ; pop ESI
pop edx ; pop EDX
pop ecx ; pop ECX
pop ebx ; pop EBX
pop eax ; pop EAX
ret
; -----------------------------------------------------------------------------
; Data
; -----------------------------------------------------------------------------
DATA_SECTION
; ------------- Days in month - normal year
DayMonthTabN: db 31 ; January
db 28 ; February
db 31 ; March
db 30 ; April
db 31 ; May
db 30 ; June
db 31 ; July
db 31 ; August
db 30 ; September
db 31 ; October
db 30 ; November
db 31 ; December
; ------------- Days in month - leap year
DayMonthTabL: db 31 ; January
db 29 ; February
db 31 ; March
db 30 ; April
db 31 ; May
db 30 ; June
db 31 ; July
db 31 ; August
db 30 ; September
db 31 ; October
db 30 ; November
db 31 ; December
; ------------- Days from begin of the normal year
align 2, db 0
DayYearTabN: dw 0 ; (0) January
dw 31 ; (31) February
dw 31+28 ; (59) March
dw 31+28+31 ; (90) April
dw 31+28+31+30 ; (120) May
dw 31+28+31+30+31 ; (151) June
dw 31+28+31+30+31+30 ; (181) July
dw 31+28+31+30+31+30+31 ; (212) August
dw 31+28+31+30+31+30+31+31 ; (243) September
dw 31+28+31+30+31+30+31+31+30 ; (273) October
dw 31+28+31+30+31+30+31+31+30+31 ; (304) November
dw 31+28+31+30+31+30+31+31+30+31+30; (334) December
; ------------- Days from begin of the leap year
align 2, db 0
DayYearTabL: dw 0 ; (0) January
dw 31 ; (31) February
dw 31+29 ; (60) March
dw 31+29+31 ; (91) April
dw 31+29+31+30 ; (121) May
dw 31+29+31+30+31 ; (152) June
dw 31+29+31+30+31+30 ; (182) July
dw 31+29+31+30+31+30+31 ; (213) August
dw 31+29+31+30+31+30+31+31 ; (244) September
dw 31+29+31+30+31+30+31+31+30 ; (274) October
dw 31+29+31+30+31+30+31+31+30+31 ; (305) November
dw 31+29+31+30+31+30+31+31+30+31+30; (335) December
; ------------- Hash table to quick find month (index = day >> 4, 0 to 22)
DayYearHash: db 1 ; 0 to 15: Jan
db 2 ; 16 to 31: Jan, Feb
db 2 ; 32 to 47: Feb
db 3 ; 48 to 63: Feb, Mar
db 3 ; 64 to 79: Mar
db 4 ; 80 to 95: Mar, Apr
db 4 ; 96 to 111: Apr
db 5 ; 112 to 127: Apr, May
db 5 ; 128 to 143: May
db 6 ; 144 to 159: May, Jun
db 6 ; 160 to 175: Jun
db 7 ; 176 to 191: Jun, Jul
db 7 ; 192 to 207: Jul
db 8 ; 208 to 223: Jul, Aug
db 8 ; 224 to 239: Aug
db 9 ; 240 to 255: Aug, Sep
db 9 ; 256 to 271: Sep
db 10 ; 272 to 287: Sep, Oct
db 10 ; 288 to 303: Oct
db 11 ; 304 to 319: Oct, Nov
db 12 ; 320 to 335: Nov, Dec
db 12 ; 336 to 351: Dec
db 12 ; 352 to 366: Dec
; ------------- Days from 1/1/1600
align 4, db 0
Days1600: dd 0 ; 1/1/1600 (0)
dd 100*365+25 ; 1/1/1700 (36525)
dd 200*365+25+24 ; 1/1/1800 (73049)
dd 300*365+25+2*24 ; 1/1/1900 (109573)
dd 400*365+25+3*24 ; 1/1/2000 (146097)
dd 500*365+2*25+3*24 ; 1/1/2100 (182622)
dd 600*365+2*25+4*24 ; 1/1/2200 (219146)
dd 700*365+2*25+5*24 ; 1/1/2300 (255670)
dd 800*365+2*25+6*24 ; 1/1/2400 (292194)
dd 900*365+3*25+6*24 ; 1/1/2500 (328719)
dd 1000*365+3*25+7*24 ; 1/1/2600 (365243)
dd 1100*365+3*25+8*24 ; 1/1/2700 (401767)
dd 1200*365+3*25+9*24 ; 1/1/2800 (438291)
dd 1300*365+4*25+9*24 ; 1/1/2900 (474816)
dd 1400*365+4*25+10*24 ; 1/1/3000 (511340)
dd 1500*365+4*25+11*24 ; 1/1/3100 (547864)
dd 1600*365+4*25+12*24 ; 1/1/3200 (584388)
; ------------- Hash table to quick find century (index = day >> 15, 0 to 18)
Days1600Hash: db 16 ; 0..32767: 16
db 17 ; 32768..65535: 16,17
db 18 ; 65536..98303: 17,18
db 19 ; 98304..131071: 18,19
db 20 ; 131072..163839: 19,20
db 21 ; 163840..196607: 20,21
db 22 ; 196608..229375: 21,22
db 23 ; 229376..262143: 22,23
db 24 ; 262144..294911: 23,24
db 24 ; 294912..327679: 24
db 25 ; 327680..360447: 24,25
db 26 ; 360448..393215: 25,26
db 27 ; 393216..425983: 26,27
db 28 ; 425984..458751: 27,28
db 29 ; 458752..491519: 28,29
db 30 ; 491520..524287: 29,30
db 31 ; 524288..557056: 30,31
db 32 ; 557056..589823: 31,32
db 32 ; 589824..609226: 32
; -----------------------------------------------------------------------------
; Uninitialized data
; -----------------------------------------------------------------------------
BSS_SECTION
|