;*; Updated on 01-Mar-94 at 3:26 PM by Jim Randazzo; edit time: 0:00:45
;JULIAN.M68             Convert MMDDYY date to Julian Date Subroutine
;
; Author..............  Jalal E. Raissi
; Installation........  Mini-Microcomputer Consultants
; Last Date Modified..  April 10, 1984
; Reason for Change...  Added the System Date routine. JER
;
; Purpose.............  To edit dates in MMDDYY form and return their value
;                       in number of days since 01/01/00.
;
;       XCALL JULIAN,SNDDTE,RCVDTE,FLGDTE
;
; Where:
;       MAP1 SNDDTE,S,6
;       MAP1 RCVDTE,F,6
;       MAP1 FLGDTE,B,1
;
; And:
;       A4 = address of SNDDTE
;       A5 = address of RCVDTE
;       A2 = address of FLGDTE
;

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  MMCRT
       SEARCH  TRM

VMAJOR=1.
VMINOR=1.
VSUB=0.
VEDIT=0.
VWHO=0.

       OBJNAM  .SBR

       PHDR    -1,PV$RSM,PH$REE!PH$REU

       CLR     D0              ; clear D0
       CLR     D1              ; clear D1
       CLR     D2              ; clear D2
       MOV     A3,A1           ; move A3 to A1
       MOVW    @A1,D1          ; look at the argument count
       CMPB    D1,#3           ; three arguments must be passed
       JLT     LESARG          ; if less, let'm know
       CLR     D4              ; clear index register
       MOVW    2(A1)[D4],D1    ; move argument type to D1
       CMPB    D1,#2           ; is it string?
       JNE     NOSTR           ; if not, let'm know
       MOVL    4(A1)[D4],A4    ; move address of SNDDTE to A4
       MOVL    10(A1)[D4],D1   ; move size of SNDDTE to D1
       CMPB    D1,#6           ; must be at least 6 bytes
       JLT     SERROR          ; if not, let'm know
       ADD     #12,D4          ; step to next argument passed
       MOVW    2(A1)[D4],D1    ; move argument type to D1
       CMPB    D1,#4           ; is it floating point?
       JNE     NOFLT           ; if not, let'm know
       MOV     4(A1)[D4],A5    ; move address of RCVDTE to A5
       ADD     #12,D4          ; step to next argument passed
       MOVW    2(A1)[D4],D1    ; move argument type to D1
       CMPB    D1,#6           ; is it binary?
       JNE     NOBIN           ; if not, let'm know
       MOV     4(A1)[D4],A2    ; move address of FLGDTE to A2
       MOVB    @A2,D1          ; move FLGDTE to D1
       CMPB    D1,#2           ; System Date wished?
       JNE     SKPSYS          ; if not, skip System Date routine
;::::::::::::::::::::::::::
;       SYSTEM DATE       :
;::::::::::::::::::::::::::
; The following routine up to [SKPSYS:] label reads the System Date  and
; stores it in SNDDTE variable.  It does what AlphaACCOUNTING subroutine
; RDATE.SBR does and more.   It returns dates prior to first of November
; in the form 0XXXXX instead of XXXXX thereby taking the masking routine
; off programmers' hands!
       CLR     D3              ; clear D3
       CLR     D4              ; clear D4
       CLR     D5              ; clear D5
       GDATES  D4              ; get System Date
       SWAP    D4              ; exchange halves
       MOVB    D4,D5           ; move MONTH to D5
       MOV     D4,D3           ; move entire word to D3
       RORW    D3,#10          ; rotate 8 bits
       AND     #377,D3         ; get DAY
       SWAP    D4              ; exchange again
       AND     #377,D4         ; get YEAR
       MOV     D4,D2           ; move year to D2
       CMPB    D5,#12          ; is MONTH 10?
       BLT     ZEROM           ; if less, go to ZEROM
       MOVB    #61,D0          ; set MONTH's 1st digit to 1
       MOV     D5,D1           ; move MONTH's 2nd digit to D1
       SUBB    #12,D1          ; single out the @nd digit
       BR      FSTMM           ; go to FSTMM
ZEROM:  MOVB    #60,D0          ; set MONTH's 1st digit to 0
       MOV     D5,D1           ; move MONTH's 2nd digit to D1
FSTMM:  MOVB    D0,(A4)+        ; move MONTH's 1st digit to SNDDTE[1,1]
       ADDB    #60,D1          ; ASCII 2nd digit!
       MOVB    D1,(A4)+        ; move MONTH's 2nd digit to SNDDTE[2,2]
       CLR     D0              ; clear D0
       CMPB    D3,#12          ; is DAY 10?
       BLT     ZEROD           ; if less, go to ZEROD
       MOVB    D3,D0           ; move DAY to D0
       DIV     D0,#12          ; single out DAY's 1st digit
       MOVB    D0,D4           ; move it to D4
       MUL     D4,#12          ; multiply by 10
       SUB     D4,D3           ; get DAY's 2nd digit
       MOV     D3,D1           ; put it in D1
       ADDB    #60,D0          ; ASCII DAY's 1st digit
       BR      FSTDD           ; go to FSTDD
ZEROD:  MOVB    #60,D0          ; set DAY's 1st digit to 0
       MOV     D3,D1           ; move DAY's 2nd digit to D1
FSTDD:  MOVB    D0,(A4)+        ; move DAY's 1st digit to SNDDTE[3,3]
       ADDB    #60,D1          ; ASCII 2nd digit!
       MOVB    D1,(A4)+        ; move DAY's 2nd digit to SNDDTE[4,4]
       CLR     D0              ; clear D0
       CMPB    D2,#12          ; is YEAR 10?
       BLT     ZEROY           ; if less, go to ZEROY
       MOV     D2,D0           ; move YEAR to D0
       DIV     D0,#12          ; single out YEAR's 1st digit
       MOV     D0,D4           ; move it to D4
       MUL     D4,#12          ; multiply by 10
       SUB     D4,D2           ; get YEAR's 2nd digit
       MOV     D2,D1           ; put it in D1
       ADDB    #60,D0          ; ASCII YEAR's 1st digit
       BR      FSTYY           ; go to FSTYY
ZEROY:  MOVB    #60,D0          ; set YEAR's 1st digit to 0
       MOV     D2,D1           ; move YEAR's 2nd digit to D1
FSTYY:  MOVB    D0,(A4)+        ; move YEAR's 1st digit to SNDDTE[5,5]
       ADDB    #60,D1          ; ASCII 2nd digit!
       MOVB    D1,(A4)+        ; move YEAR's 2nd digit to SNDDTE[6,6]
       MOVL    4(A1),A4        ; move address of SNDDTE to A4
       CLR     D0
       CLR     D1
       CLR     D2
SKPSYS: CLR     D5              ; clear D5
       MOVB    (A4)+,D5        ; move MONTH's 1st digit to D5
       SUB     #60,D5          ; convert it to Octal
       CMPB    D5,#1           ; compare it to 1!
       JGT     MERROR          ; if greater, let'm know
       CMPB    D5,#0           ; compare it to 0!
       JLT     MERROR          ; if less, let'm know
       MUL     D5,#12          ; multiply it by 10
       MOVB    (A4)+,D0        ; move MONTH's 2nd digit to D0
       SUB     #60,D0          ; convert it to Octal
       ADDB    D0,D5           ; save it in D5!
;::::::::::::::::::::::::::::::::::::::::::::
;       find DAYS in and before MONTH       :
;::::::::::::::::::::::::::::::::::::::::::::
MONTH:  CMPB    D5,#14          ; MONTH greater than 12?
       JGT     MERROR          ; yes, let'm know
       CMPB    D5,#1           ; MONTH less than 1?
       JLT     MERROR          ; yes, let'm know
       MOV     #37,D2          ; start number of days
       MOV     #0,D4           ; days before January
       CMPB    D5,#1           ; is it January?
       JEQ     DAY             ; if yes, do DAY
       MOV     D2,D4           ; days before February
       MOV     #35,D2          ; maximum days in February
       CMPB    D5,#2           ; is it February?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; maximum days in March
       CMPB    D5,#3           ; is it March?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #36,D2          ; maximum days in April
       CMPB    D5,#4           ; is it April?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; maximum days in May
       CMPB    D5,#5           ; is it May?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #36,D2          ; maximum days in June
       CMPB    D5,#6           ; is it June?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; maximum days in July
       CMPB    D5,#7           ; is it July?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; maximum days in August
       CMPB    D5,#10          ; is it August?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #36,D2          ; maximum days in September
       CMPB    D5,#11          ; is it September?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; maximum days in October
       CMPB    D5,#12          ; is it October?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #36,D2          ; maximum days in November
       CMPB    D5,#13          ; is it November?
       JEQ     DAY             ; if yes, do DAY
       CALL    ACCUM           ; accumulate days
       MOV     #37,D2          ; Maximum days in December
;::::::::::::::::::::::::::::::::
;       get and edit DAY        :
;::::::::::::::::::::::::::::::::
DAY:    CLR     D1              ; setup D1
       MOVB    (A4)+,D1        ; move DAY's 1st digit to D1
       SUB     #60,D1          ; convert it to Octal
       MUL     D1,#12          ; multiply by 10
       MOVB    (A4)+,D0        ; move DAY's 2nd digit to D0
       SUB     #60,D0          ; convert it to Octal
       ADDB    D0,D1           ; D1 = (1st digit) * 10 + 2nd digit
       CMPB    D1,D2           ; compare with maximum in month
       JGT     DERROR          ; if greater, let'm know!
       CMPB    D1,#1           ; compare it with 1!
       JLT     DERROR          ; if less, let'm know!
       ADD     D1,D4           ; add DAY (days in month) to days before
       MOV     D1,D2           ; move DAY to D2
;::::::::::::::::::::::::::::::::
;       get and edit YEAR       :
;::::::::::::::::::::::::::::::::
YEAR:   CLR     D1              ; clear D1
       MOVB    (A4)+,D1        ; move YEAR's 1st digit to D1
       CMPB    D1,#60          ; compare it with 0!
       JLT     YERROR          ; if less, let'm know!
       CMPB    D1,#71          ; compare it with 9!
       JGT     YERROR          ; if greater, let'm know!
       SUB     #60,D1          ; convert it to Octal
       MUL     D1,#12          ; multiply by 10
       MOVB    (A4)+,D0        ; move YEAR's 2nd digit to D0
       SUB     #60,D0          ; convert it to Octal
       ADDB    D0,D1           ; D1 = (1st digit) * 10 + 2nd digit
       CMPB    D1,#0           ; compare it with 0!
       JLT     YERROR          ; if less, let'm know!
       CMPB    D1,#143         ; compare it with 99!
       JGT     YERROR          ; if greater, let'm know!
       MOVB    D1,D0           ; put it in D0
       DIV     D0,#4           ; divide it by 4
       MOVB    D0,D3           ; add number of leap days since
       MUL     D0,#4           ; multiply it by 4
       CMPB    D0,D1           ; is it leap year?
       BEQ     SKPINC          ; if not, don't add
       CMP     D5,#2           ; compare it with February?
       BNE     SKPCHK          ; if not, go to SKPCHK
       CMP     D2,#34          ; compare it to maximum (28) in a leap year!
       JGT     DERROR          ; if greater,let'm know!
SKPCHK: CMP     D4,#74          ; and Jan or Feb?
       BGE     SKPINC          ; if not, go to SKPINC
       INC     D4              ; increment by one
SKPINC: MUL     D1,#555         ; multiply by 365
       ADD     D1,D4           ; add MMDD
       ADD     D3,D4           ; leap days
       DEC     D4              ; decrement by one
;::::::::::::::::::::::::::::
;       get back to BASIC   :
;::::::::::::::::::::::::::::
EXT:    MOV     D4,D1           ; move number of days since 01/01/00 to D1
       FLTOF   D1,@A5          ; convert it to floating point in RCVDTE!
       MOVB    #0,@A2          ; tell'm it all went ok!!
       RTN                     ; go back to BASIC
;:::::::::::::::::::::::::::::::::::
;       accumulate DAYs corner     :
;:::::::::::::::::::::::::::::::::::
ACCUM:  ADD     D2,D4           ; add D2 to D4
       RTN                     ; fetch next instruction from PC
;:::::::::::::::::::::::::::
;       error routines     :
;:::::::::::::::::::::::::::
LESARG: CALL    SETUP
       TYPE    <Arguments are LT 3.>
       JMP     PROMPT
NOSTR:  CALL    SETUP
       TYPE    <SNDDTE is not string.>
       JMP     PROMPT
SERROR: CALL    SETUP
       TYPE    <SNDDTE is LT 6 bytes.>
       JMP     PROMPT
NOFLT:  CALL    SETUP
       TYPE    <RCVDTE is not floating point.>
       JMP     PROMPT
NOBIN:  CALL    SETUP
       TYPE    <FLGDTE is not binary.>
       JMP     PROMPT
MERROR: CALL    SETUP
       TYPE    <Month>
       BR      BPROMPT
DERROR: CALL    SETUP
       TYPE    <Day>
       BR      BPROMPT
YERROR: CALL    SETUP
       TYPE    <Year>
BPROMPT:TYPE    < is invalid.>
PROMPT: MMCRT   #30,#63         ; set up line 24
       TYPE    <Press [RETURN] to redo!>
       TIN                     ; one key stroke
       MMCRT   #30,#1          ; set up line 24
       MOV     #177411,D1      ; ? TAB(-1,9);
       TCRT                    ; do it!
       MOVB    #1,@A2          ; let'm know it all did not go ok!
       RTN                     ; go back to BASIC
SETUP:  MOV     #7,D1           ; set up bell
       TTY                     ; do it
       MMCRT   #30,#1          ; set up line 24
       RTN                     ; fetch next instruction from PC
       END                     ; end of source program