;真正的万年历:84bytes的51ASM
;==SUB_WNL===万年历==*DengMiao*2004-06-01*****GuangZhou******
SJDATA30H;世纪BCD00TO99
NHDATA31H;年号BCD00TO990000TO9999年
YFDATA32H;月份BCD01TO12
org000h
MOVSP,#40H
MOVSJ,#21H;2004-05
MOVNH,#01H
MOVYF,#4H
ACALLSUB_WNL
SJMP$
;===============SUB_WNL===================
;入口:
;SJDATA30H;世纪BCD00TO99
;NHDATA31H;年号BCD00TO990000TO9999年
;YFDATA32H;月份BCD01TO12
;出口
;ACC--本月天数BCD28to31
;B--本月1日的星期数1to6==星期1to星期6
;0--星期日
;使用:ACC,B,R5,R6
;STACK:3bytes(不包括调用)
ORG50H
SUB_WNL:
PUSHPSW
MOVA,SJ
ACALLBCD2BIN_MOD4
;x400年:(大周期)
;=146097天=7*20871+0天
;x100年:
;000年=7*0+0+1-11=0*2+1****
;100年=7*5217+7+1-22=1*2
;200年=7*10435+7+1-44=2*2
;300年=7*15653+7+1-66=3*2
;{1,2,4,6}
MOVA,R6;A=R6=SJ_BINMOD4
RLCA;A=A*2+CA={1,2,4,6}****
XRLA,#10000111B;A=87H-A;边界调整
MOVR5,A;A={86H,85H,83H,81H};R5:星期
MOVA,NH
JZWNL_1
ACALLBCD2BIN_MOD4
XCHA,R5
SUBBA,R5;0年;0=0+0+1+(-1)***
MOVR5,A
WNL_1:
MOVA,YF
ADDA,#(WNL_TAB-$-4)
MOVCA,@A+PC
MOVR6,A
SWAPA
ACALLWNL_F0;大年对>=3月调整准备
ADDCA,R5;月调整
MOVB,#7
DIVAB;B=AMOD7
MOVA,R6
ACALLWNL_F0;大年调整准备
ADDCA,#28
POPPSW
RET
WNL_TAB:
DB3*2+5*32+0;1BIT0:"2月"标志
DB0*2+1+1*32+0;2**BIT1..2:月大小
DB3*2+1*32+16;300:28天
DB2*2+4*32+16;401:----
DB3*2+6*32+16;510:30天
DB2*2+2*32+16;611:31天
DB3*2+4*32+16;7BIT3:0-----
DB3*2+7*32+16;8BIT4:0:1/2月
DB2*2+3*32+16;91:>=3月
WNL_F0:;6BYTES;大年调整准备
RRCA;0AH
ANLA,#07H;0BH
;0CH
ANLC,F0;0DH
;0EH
RET;0FH
DB3*2+5*32+16;10HBIT5..7:星期调整数
DB2*2+1*32+16;11H0:---
DB3*2+3*32+16;12H1-7:调整数
BCD2BIN_MOD4:
;功能:A.1BYTESBCDTOBIN
;B.MOD4
;C.MUL2
;入口:
;A:SJORNH
;F0:大世纪
;出口
;ACC--(BIN(A)4)*2-(BIN(A)MOD4)-F0
;R6--BIN(A)MOD4
;C--IIF((BIN(A)MOD4)=0,1,0)
;使用:ACC,B,R6,PSW
;STACK:0bytes(不包括调用)
MOVR6,A;BCD==>BIN
ANLA,#0F0H;16X+Y==>10X+Y
SWAPA
MOVB,#(256-6);(256-6)*X+(16X+Y)
MULAB;
ADDA,R6;=256X+(10X+Y)
MOVR6,A;MOD4
ANLA,#3
XCHA,R6;R6=BINMOD4={0,1,2,3}
;X4年:3*365+366=7*209+(-2)**
XRLA,R6;A=(BIN4)
RRA;A=(BIN4)*2**
MOVC,F0;大世纪调整
SUBBA,R6
;X1年:
;0年0=0+0+1+(-1)***
;1年366=7*52+1+1
;2年366+365=7*104+2+1
;3年366+365+365=7*156+3+1
;{-1,1,2,3}
CJNER6,#1,$+3;C=IIF(R6>=1,0,1)
MOVF0,C;C=1为大年/大世纪
RET
;-----------------------------
END;========ENDOFFILE