; DATE.SBR ; VER 1.0 8608.12 ; ; ; ; PROPRIETARY PROGRAM MATERIAL ; ; THIS MATERIAL IS THE PROPERTY OF JEFF STUYVESANT, ; 12307 PACIFIC AVE, APT 2,MAR VISTA, CALIF. ,90066 ; PERMISSION TO COPY AND USE IS GRANTED FOR ; NON-PROFIT USES ONLY. ; ; Copyright (c) 1986 JEFF STUYVESANT SEARCH SYS SEARCH SYSSYM SEARCH TRM OBJNAM DATE.SBR RADIX 8. VMAJOR = 1. VMINOR = 0. VSUB = 0. VEDIT = 0. VWHO = 0. ;MACROS DEFINE GET.D O.SET,DEST MOV O.SET(A3),DEST ENDM DEFINE GET.I O.SET,DEST MOV O.SET(A3),DEST SWAP DEST ENDM DEFINE SAV.D O.SET,SORC MOV SORC,O.SET(A3) ENDM DEFINE SAV.I O.SET,SORC SWAP SORC MOV SORC,O.SET(A3) ENDM ;EQUATES ; DSECT A.SIZE = 8. A.ADDR = 4. V.DATE = 0. V.INTL = 0. V.BASE = 4. V.MODE = 8. V.LEAP = 8. ; PSECT PHDR -1,0,PH$REE!PH$REU START: ; A3 POINTS TO BASE OF ARG LIST CMPW @A3,#1 ; ONLY ONE ARG JNE SBR.ERROR CMP A.SIZE(A3),#10. ; 10 BYTES IN SIZE JLO SBR.ERROR MOV A.ADDR(A3),A3 ; GET ADDR OF VARIBLE MOVW V.MODE(A3),D5 ; MOV MODE INTO D5 BEQ SBR.ERROR ; ERROR IF ZERO CMPW D5,#5. ; IS IT MODE 5 JEQ MODE.5 ; BR TRUE BHI SBR.ERROR ; ERROR IF GREATER ; PROCESS MODE 1 TO 4 GET.D V.DATE,D6 ; GET DATE'SEP BEQ DATE.ERROR ; CANT BE ZERO CALL $DTO.I ; CALC DATE TO INTERNAL BEQ DATE.ERROR ; INVALID DATE IF Z FLAG MOVW D7,V.LEAP(A3) ; SAVE LEAP'YEAR FLAG CMPW D5,#4. ; IS IT MODE 4? BEQ MODE.4 ; BR IF YES ; DATE ENTERED AS INTERNAL IN D6 MOV D6,D3 CALL DOW ; CALC DAY OF WEEK SAVE IN D3 CMPW D5,#2. BLO EXIT ; LOW IS ONLY MODE 1 BEQ MODE.2 ; BR IF = MODE 2 ; MUST BE MODE 3 MODE.3: ; SECOND DATE IN DATE'BASE TST V.BASE(A3) ; BASE CANT=0 BEQ DATE.ERROR ; BR IF = SAV.I V.INTL,D6 ; SAVE DATE AS DAYS GET.D V.BASE,D6 ; GET DATE'BASE(AS DATE) BEQ DATE.ERROR ; CANT BE ZERO CALL $DTO.I ; CALC DATE TO INTERNAL BEQ DATE.ERROR ; INVALID DATE IF Z FLAG GET.I V.INTL,D7 ; GET DATE'SEP(AS'DAYS) XCH D6,D7 ; SET INTO PROPER ORDER ; D6= DATE(AS DAYS [LARGER]) ; D7= DATE'BASE(AS DAYS [SMALLER]) SUB.01: CMP D7,D6 ; COMPARE THE TWO DATES(AS DAYS) BHI DATE.ERROR ; BR IF BASE > SEP. SUB D7,D6 ; SEP-BASE= DIFFERENCE ; END OF PROGRAM EXIT: SAV.I V.INTL,D6 ; SAVE DAYS EXIT$: SAV.I V.BASE,D3 ; SAVE DOW RTN ;MODE OR ARG IN ERROR SBR.ERROR: MOV #0,V.INTL(A3) ; USED WHEN PARAMETERS MOV #0,V.BASE(A3) ; ARE IN ERROR SETW V.MODE(A3) ; MODE/#OF ARG ETC. RTN ; DATA IN ERROR DATE.ERROR: SET V.INTL(A3) ; USED WHEN VARIBLES ARE SET V.BASE(A3) ; IN ERROR SETW V.MODE(A3) ; DATE NOT DATE/ ETC RTN MODE.2: ; D6=DATE(AS DAYS) ; SUB DATE'BASE(AS DAYS) AND FINISH GET.I V.BASE,D7 ; GET DATE'BASE(AS DAYS) ; D7= DATE(AS DAYS [LARGER]) ; D6= DATE'BASE(AS DAYS [SMALLER]) BR SUB.01 ; SUB AND SAVE MODE.4: ; D6=DATE(AS DAYS) ; ADD DATE'BASE(AS DAYS) SEND BACK ; DATE'INTERNAL GET.I V.BASE,D7 ; GET DATE'BASE(AS DATE) ADD D7,D6 ; CALC NEW DAYS MOV D6,D4 ; CALL USES D4 BR CALC.INTL ; CALC NEW DATE MODE.5: ; GET D4 AS DAYS ; RETURN DATE MOVW #0,V.MODE(A3) ; CLEAR MODE GET.I V.DATE,D4 ; GET DATE(AS DAYS) BEQ DATE.ERROR ; BR IF = 0 CALC.INTL: MOV D4,D3 ; SET UP FOR DOW CALL DOW ; CALC DAY OF WEEK CALL $ITO.D ; CONVERT TO DATE BEQ DATE.ERROR ; DAYS IN ERROR SAV.D V.DATE,D6 ; SAVE IT AND FINISH BR EXIT$ $ITO.D: ; D4 CONTAINS DAYS TO BE CONVERTED SAVE D0-D2,A5 SUB #2351425.,D4 ; CORRECT FROM AM FORMAT CMP D4,#0. ; CMP TO 0 JLOS NO.GOOD ; NO GOOD IF 0 OR LESS MOV #146097.,D6 ; SET DIVISOR INTO D6 SUB #12.,SP ; GRAB SOME WORKSPACE LEA A6,(SP) ; A6 TO POINT TO IT FLTOF D6,@A6 ; CONVERT D6 TO FLOAT . ADD #6.,A6 ; POINT TO NEW LOCATION MOV D4,D6 ; GET DAYS TO CONVERT ADD #364.,D6 ; CORRECTION OF 1 YR-1 FLTOF D6,@A6 ; CNVT TO FLOAT . MOV SP,A5 ; SAVE SP FDIV A5,A6 ; DIV THE NUMBERS MOV A6,A5 ; GET BASE OF NUMBERS FFTOL @A5,D6 ; CNVT FROM FLOAT .->D6 ADD #12.,SP ; RESET SP INC D6 ; ADD ONE TO ANSWER MOV D4,D0 ; SAVE IT ADD #364.,D0 ; ADD CORRECTION 1 YR-1 SUB D6,D0 ; CALC DIFERENCE MOV D0,D1 ; SAVE IT P2: ; CALCULATION PART TWO DIV D0,#36524. ; DIVIDE D0 AND #177777,D0 ; ELIMINATE REMAINDER INC D0 ; ADD 1 ADD D0,D1 ; ADD TO SAVED NUMBER MOV D1,D0 ; AND SAVE A COPY P3: ; CALCULATION PART THREE DIV D0,#1461. ; DIVIDE D0 AND #177777,D0 ; ELIMINATE REMAINDER SUB D0,D1 ; SUB FROM SAVED NUMBER P4: ; CALCULATION PART FOUR DIV D1,#365. ; DIVIDE BY DAYS IN YEAR AND #177777,D1 ; ELIMINATE REMAINDER ; D1 = YEAR ;@SP = #OF DAYS ENTERED MOV D1,D6 ; SAVE YEAR CALL CALC.D ; CALC # OF DAYS TO 01/00/YEAR MOV D4,D1 ; SAVE DAYS ; D0 = # OF DAYS FROM 01/01/01 TO 01/00/YEAR ; D1 = # OF DAYS FROM 01/01/01 TO MO/DAY/YEAR ; D4 = " " " " " ; D6 = YEAR ; D7 = 1 FOR LEAP YEAR/ 0 IF NOT SUB D0,D1 ; CALC DAYS ; D1 = # OF DAYS FROM 01/00/YEAR TO MO/DAY/YEAR ; D6 = YEAR ; D7 = 1 FOR LEAP YEAR/ 0 IF NOT ; DETERMINE MO AND DAY MOVW #1,D0 ; SET MO POINTER CLR D2 ; PRE-CLEAR 10$: MOVB EOM[~D0],D2 ; GET DAYS IN MONTH (D0) CMPW D0,#2 ; IS IF FEBUARY BNE 15$ ; BR IF NOT ADDB D7,D2 ; YES ADD D7= LEAP YEAR 15$: CMPW D1,D2 ; CMP DAYS TO DATE TO EOM BLOS 20$ ; IF LESS WE FOUND IT SUBW D2,D1 ; SUB DAYS IN MO FROM DAYS TO DATE INCW D0 ; INC MO POINTER BR 10$ ; TRY AGAIN ; DATE FOUND PACKIT WITH YEAR 20$: ; D0 = MONTH ; D1 = DAY ; D6 = YEAR LSLW D1,#8. ; SHIFT LEFT EIGHT BITS MOVB D0,D1 ; SET LOWER BYTE =MO ; D1.W = MO/DAY MOV #16.,D2 ; SET COUNTER ROL D6,D2 ; ROLL LEFT 16 BITS MOVW D1,D6 ; SET LOW WORD=MO/DAY ROR D6,D2 ; ROLL RIGHT 16 BITS JMP FIN ; ALL DONE ; D6 = MO/DAY/YEAR ; PROCESS ERRORS NO.GOOD: REST D6 ; RET REGISTERS DATE.NO.GOOD: LCC #PS.Z ; INDICATE ERROR FIN: REST D0-D2,A5 ; REST REGISTERS RTN ; LIST OF DAYS IN MONTH EOM: BYTE 0,31.,28.,31.,30.,31.,30.,31.,31.,30.,31.,30.,31. EVEN $DTO.I: ; ENTER D6= DATE IN SEP FORMAT (NOT AM STANDARD) SAVE D0-D2,A5 ; SAVE REGISTERS CMPW D6,#10000. ; YEAR MAX IS 10,000 DECIMAL BHI DATE.NO.GOOD ; BR IF NO GOOD CALL CALC.D ; CALC DAYS TO 01/00/YEAR ; D0=NUMBER OF DAYS TO FIRST OF YEAR -1 ; D7= LEAP YEAR 1=YES 0=NO MO.VER: ; VERIFY MONTH SWAP D6 ; GET MONTH IN LOWER BYTE CMPB D6,#12. ; CHECK WITH 12 MONTHS BHI DATE.NO.GOOD ; IF HI NO GOOD ; CALC UP TO MONTH CLR D2 ; PRE-CLEAR MOV #1,D1 ; SET MONTH POINTER 10$: CMPB D1,D6 ; AT MONTH YET BEQ DAY.VER ; BR IF YES MOVB EOM[~D1],D2 ; NO GET DAYS IN MONTH PRIOR ADD D2,D0 ; ADD TO CUMULATIVE INCB D1 ; INC MO POINTER BR 10$ ; BR AGAIN DAY.VER: ; VERIFY DAY GIVEN ROLW D6,#8. ; ROLL WORD LEFT 8 BITS CMPB D6,EOM[~D1] ; CMP DAYS IN MO TO PASSED BHI 20$ ; BR IF HI MAYBE NO GOOD MOVB D6,D2 ; SET D2=PASSED VALUE ADD D2,D0 ; ADDIT TO CUMLUATIVE CMPB D7,#1 ; LEAP YEAR ? BNE 10$ ; BR IF NOT CMPB D1,#2 ; PAST FEBUARY BLOS 10$ ; BR IF NOT ADD #1,D0 ; INC CUMULATIVE ; ALL DONE 10$: BR FINISH ; DAYS PAST MAY BE TOO HIGH 20$: CMPB D1,#2 ; MO PASSED FEBUARY BNE DATE.NO.GOOD ; BR IF NOT CMPB D7,#1 ; THIS A LEAP YEAR BNE DATE.NO.GOOD ; BR IF NOT CMPB D6,#29. ; ONLY #29 ALLOWED BNE DATE.NO.GOOD ; BR IF NOT ADD #29.,D0 ; INC D0 BY 29 DAYS ; ALL DONE FINISH: MOV D0,D6 ; RESET D6 ADD #2351425.,D6 ; CORRECT TO AM FORMAT REST D0-D2,A5 ; REST REGISTERS RTN ; GO BACK ; CALC DAYS IN YEAR ; D6= YEAR PASSED CALC.D: CLR D7 ; PRE-CLEAR CLR D0 ; PRE-CLEAR DECW D6 ; SUB 1 FROM YEAR PASSED MOVW D6,D0 ; SAVE IT MUL D0,#365. ; MUL BY 365 DAYS A YEAR CLR D1 ; PRE-CLEAR MOVW D6,D1 ; GET YEAR DIV D1,#4. ; DIV BY 4 = # OF LEAP YEARS AND #177777,D1 ; ELIMINATE REMAINDER ADD D1,D0 ; ADD TO CUMULATIVE MOVW D6,D1 ; GET YEAR DIV D1,#100. ; CHECK FOR 100 YEAR EXCEPTIONS AND #177777,D1 ; ELIMINATE REMAINDER SUB D1,D0 ; SUB FROM CUMULATIVE MOVW D6,D1 ; GET YEAR DIV D1,#400. ; CHECK FOR 400 YEAR EXCEPTIONS AND #177777,D1 ; ELIMINATE REMAINDER ADD D1,D0 ; ADD TO CUMULATIVE LEAP.YEAR: INCW D6 ; RESET TO ORIGINAL YEAR PASSED CLR D1 ; PRE-CLEAR MOVW D6,D1 ; GET YEAR DIV D1,#4. ; DIV BY 4 (PER LEAP YEAR CYCLE) SWAP D1 ; GET REMAINDER TSTW D1 ; CHECK FOR ZERO BNE 30$ ; BR IF NOT MOVB #1,D7 ; SET LOW BYTE TO 1 - FLAG YES 10$: ; CHECK FOR 100 YEAR EXCEPTION CLR D1 ; PRE-CLEAR MOVW D6,D1 ; GET YEAR DIV D1,#100. ; DIV BY 100 (CYCLE) SWAP D1 ; GET REMAINDER TSTW D1 ; IS IT ZERO BNE 30$ ; BR IF NOT CLRB D7 ; YES SO UN SET FLAG 20$: ; CHECK FOR 400 YEAR EXCEPTION CLR D1 ; PRE-CLEAR MOVW D6,D1 ; GET YEAR DIV D1,#400. ; DIV BY 400 (CYCLE) SWAP D1 ; GET REMAINDER TSTW D1 ; IS IT ZERO BNE 30$ ; BR IF NOT MOVB #1,D7 ; YES SET FLAG 30$: RTN ; ALL DONE ;CALC DAY OF WEEK ; D3=DATE AS DAYS DOW: MOV D3,D2 ; SAVE DAYS ; ADJUST DAYS DIV HAS MAX LIMIT DIV D2,#343. ; DIV LARGE NUMBER DIV BY 7 AND #177777,D2 ; ELIMINATE REMAINDER BEQ 10$ ; CONT IF NO QUO MUL D2,#343. ; MUST ADJUST CALC D2*343. SUB D2,D3 ; SUB FROM PASED NUMBER 10$: DIV D3,#7. ; CALC MODULO 7 SWAP D3 ; GET REMAINDER AND #177777,D3 ; STRIP QUO RTN ; D3= DOW END