Farba Research PDP-11 Assembler Example

        .TITLE  JULIAN
        .IDENT  /MAC/

;SUBROUTINE TO CALCULATE JULIAN DATE FROM YEAR, MONTH, DAY
;
;WRITTEN BY:  E. NICHOLAS CUPERY  03 FEBRUARY 1976

;SUBROUTINE JULIAN IS REENTRANT, AND PRESERVES ALL REGISTERS
;SUBROUTINE JULIAN REQUIRES FIVE WORDS OF STACK SPACE
;SUBROUTINE JULIAN OCCUPIES 76. WORDS OF MEMORY



;FORTRAN CALL:   "CALL JULIAN(NYEAR,NMONTH,NDAY,NANSER,NSTAT)"
;
;THIS FORTRAN CALL WILL CAUSE A "JSR PC, JULIAN"
;WITH R5 POINTING AT A 6-WORD BLOCK DESCRIBED BELOW:
;
;
        ;1ST WORD CONTAINS THE NUMBER OF ARGUMENTS (MUST BE FIVE)
        ;IN THE LOW-BYTE, AND GARBAGE IN THE HIGH-BYTE.
;
        ;2ND WORD CONTAINS THE ADDRESS OF THE YEAR (SINCE 1900)
        ;INFORMATION ("NYEAR"), WHICH MUST BE A ONE-WORD INTEGER.
;
        ;3RD WORD CONTAINS THE ADDRESS OF THE MONTH
        ;INFORMATION ("NMONTH"), WHICH MUST BE A ONE-WORD INTEGER.
;
        ;4TH WORD CONTAINS THE ADDRESS OF THE DAY
        ;INFORMATION ("NDAY"), WHICH MUST BE A ONE-WORD INTEGER.
;
        ;5TH WORD CONTAINS THE ADDRESS OF THE ONE-WORD INTEGER LOCATION
        ;("NANSER") IN WHICH THE JULIAN DATE (ANSWER) IS TO BE PLACED.
;
        ;6TH WORD CONTAINS THE ADDRESS OF THE ONE-WORD INTEGER
        ;LOCATION ("NSTAT") IN WHICH THE RETURN STATUS IS TO BE PLACED.


;NOTES: ;THE NUMBER OF ARGUMENTS MUST BE FIVE.
        ;
        ;A RETURN STATUS OF +1 INDICATES SUCCESS.
        ;A RETURN STATUS OF -1 INDICATES FAILURE.
        ;
        ;THE YEAR MUST BE RELATIVE TO 1900 (EX: 5 FOR THE YEAR 1905)
        ;THE ALGORITHM USED TO LOOK FOR LEAP-YEARS WORKS
        ;ONLY FOR CALENDAR YEARS BETWEEN 1901 AND 2099 INCLUSIVE.
        ;(WHICH MEANS THE "YEAR" INPUT MUST BE BETWEEN 1 AND
        ;199. INCLUSIVE).
        ;
        ;THE MONTH MUST BE BETWEEN 1 AND 12. INCLUSIVE.
        ;
        ;THE DAY MUST BE BETWEEN 1 AND THE MAXIMUM
        ;NUMBER OF DAYS IN THE PARTICULAR MONTH INPUT.
        ;
        ;THE CURRENT MONTH, DAY, AND YEAR CAN BE GOTTEN FROM THE FORTRAN
        ;"IDATE" SUBROUTINE (SEE PAGE B-4 OF FORTRAN USER'S GUIDE).



;ASSEMBLY LANGUAGE CALL: ;CALLS TO SUBROUTINE JULIAN FROM ASSEMBLY
                         ;LANGUAGE PROGRAMS MUST "LOOK LIKE" THE FORTRAN CALL
                         ;DESCRIBED ABOVE. HOWEVER, THE ASSEMBLY LANGUAGE
                         ;CALLER WILL PROBABLY WISH TO MAKE USE OF THE
                         ;FACT THAT "JULIAN" WILL CLEAR THE C-BIT ON
                         ;SUCCESSFUL RETURNS, AND SET THE C-BIT ON FAILURES.
        ;
        ;NOTE:  THE CURRENT MONTH, DAY, AND YEAR CAN BE GOTTEN VIA THE
        ;"GTIM$" DIRECTIVE (SEE PAGE 2-23 OF EXEC REFERENCE MANUAL).




;THE GENERAL REGISTERS ARE USED WITHIN THIS SUBROUTINE AS FOLLOWS:
;
;R0 HOLDS DAY-OF-THE-MONTH INFORMATION
;R1 HOLDS THE MONTH-OF-THE-YEAR INFORMATION
;R2 HOLDS THE YEAR INFORMATION
;R3 IS NOT USED
;R4 IS NOT USED
;R5 IS USED AS A POINTER TO ARGUMENT ADDRESSES
;
;END OF GENERAL REGISTER USAGE DESCRIPTION



JULIAN::MOV     R0,-(SP)        ;SAVE R0
        MOV     R1,-(SP)        ;SAVE R1
        MOV     R2,-(SP)        ;SAVE R2
        MOV     R5,-(SP)        ;SAVE R5
        MOV     #-1,@12(R5)     ;ASSUME ERROR (STATUS=-1)
        CMPB    #5, (R5)+       ;EXACTLY FIVE ARGUMENTS?
        BNE     ERROR           ;ANYTHING BUT FIVE IS AN ERROR
        TSTB    (R5)+           ;POINT PAST "GARBAGE" BYTE
        MOV     @(R5)+,R2       ;YEAR SINCE 1900
        BLE     ERROR           ;ERROR IF YEAR 1900 OR PREVIOUS
        CMP     #200., R2       ;LESS THAN YEAR 2100?
        BLE     ERROR           ;ERROR IF YEAR 2100 OR GREATER

;WILL NOW SEE IF YEAR IN R2 IS A LEAP-YEAR OR NOT
;NOTE THAT LEAP YEARS ARE INTEGRALLY DIVISIBLE BY 4, AND OTHERS AREN'T
        MOV     R2,R1           ;COPY THE YEAR
        CLR     R2              ;ASSUME IS NOT A LEAP-YEAR
        BIT     #3,R1           ;YEAR INTEGRALLY DIVISIBLE BY 4?
        BNE     1$              ;BR IF NO (NOT LEAP-YEAR)
        INC     R2              ;NOTE 1 EXTRA DAY IN LEAP-YEAR

;WHEN GET HERE, R2 IS 1 FOR LEAP-YEAR OR 0 FOR NON-LEAP-YEAR
1$:     MOV     @(R5)+,R1       ;MONTH OF THE YEAR
        BLE     ERROR           ;ERROR IF LESS THAN 1
        CMP     #13.,R1         ;MONTH 12. OR LESS?
        BLE     ERROR           ;ERROR IF MONTH GREATER THAN 12.
        MOV     @(R5)+,R0       ;DAY OF THE MONTH
        BLE     ERROR           ;ERROR IF LESS THAN 1

;WILL NOW SEE IF DAY-OF-MONTH LEGAL FOR THIS PARTICULAR MONTH
        DEC     R1              ;MAKE MONTH RELATIVE TO 0
        CMPB    DAYS(R1),R0     ;LEGAL DAY OF THIS MONTH?
        BHIS    OKAY            ;BR IF YES

;IF GET HERE, DAY SPECIFIED SEEMS TO LARGE FOR THIS PARTICULAR MONTH
;HOWEVER, WILL BE LEGAL IF IS 29 FEBRUARY IN A LEAP YEAR
        CMP     #29.,R0         ;IS IT THE 29TH DAY?
        BNE     ERROR           ;ERROR IF NOT
        CMP     #1,R1           ;IS THE MONTH FEBRUARY?
        BNE     ERROR           ;ERROR IF NOT
        TST     R2              ;IS IT A LEAP YEAR?
        BEQ     ERROR           ;ERROR IF NOT

;IF GET HERE, THE DAY, MONTH, AND YEAR ARE ALL LEGAL
;WILL NOW ADD DAYS IN PREVIOUS WHOLE MONTHS TO CURRENT DAY
OKAY:   ASL     R1              ;MAKE MONTHLY-TOTALS WORD INDEX
        ADD     TOTALS(R1),R0   ;ADD TO CURRENT DAY OF MONTH

;NOW HAVE THE ANSWER, UNLESS IS PAST FEBRUARY IN A LEAP YEAR
        CMP     R1, #2          ;PAST THE MONTH OF FEBRUARY?
        BLE     1$              ;BR IF NO
        ADD     R2,R0           ;ADD 1 DAY IF LEAP YEAR

;NOW HAVE THE ANSWER IN R0, AND WILL RETURN IT TO CALLER
1$:     MOV     R0,@(R5)+       ;RETURN ANSWER TO CALLER
        NEG     @(R5)+          ;CHANGE STATUS TO +1
        CLC                     ;CLEAR C-BIT TO INDICATE SUCCESS

;WILL NOW RESTORE REGISTERS AND RETURN TO CALLER
GOBACK: MOV     (SP)+,R5        ;RESTORE R5
        MOV     (SP)+,R2        ;RESTORE R2
        MOV     (SP)+,R1        ;RESTORE R1
        MOV     (SP)+,R0        ;RESTORE R0
        RTS     PC              ;RETURN TO CALLER

;IF GET HERE, AN ERROR WAS DETECTED IN INPUT INFORMATION
;WILL RETURN IMMEDIATELY TO CALLER, WITH A STATUS OF -1 AND C-BIT SET
;
ERROR:  SEC                     ;SET C-BIT TO INDICATE FAILURE
        BR      GOBACK          ;RESTORE REGISTERS AND RETURN




;TABLE OF NUMBER OF DAYS IN EACH MONTH
;NOTE THAT FEBRUARY ENTRY IS FOR NON-LEAP-YEAR
;
DAYS:   .BYTE   31.             ;31. DAYS IN JANUARY
        .BYTE   28.             ;28. DAYS IN FEBRUARY (USUALLY)
        .BYTE   31.             ;31. DAYS IN MARCH
        .BYTE   30.             ;30. DAYS IN APRIL
        .BYTE   31.             ;31. DAYS IN MAY
        .BYTE   30.             ;30. DAYS IN JUNE
        .BYTE   31.             ;31. DAYS IN JULY
        .BYTE   31.             ;31. DAYS IN AUGUST
        .BYTE   30.             ;30. DAYS IN SEPTEMBER
        .BYTE   31.             ;31. DAYS IN OCTOBER
        .BYTE   30.             ;30. DAYS IN NOVEMBER
        .BYTE   31.             ;31. DAYS IN DECEMBER
;
;END OF TABLE OF NUMBER OF DAYS IN EACH MONTH




;TABLE OF TOTAL DAYS IN YEAR PRIOR TO CURRENT MONTH
;NOTE THAT TABLE ENTRIES ARE FOR NON-LEAP-YEARS
;
TOTALS: .WORD   0               ;0.   DAYS PRIOR TO JANUARY
        .WORD   31.             ;31.  DAYS PRIOR TO FEBRUARY
        .WORD   59.             ;59.  DAYS PRIOR TO MARCH
        .WORD   90.             ;90.  DAYS PRIOR TO APRIL
        .WORD   120.            ;120. DAYS PRIOR TO MAY
        .WORD   151.            ;151. DAYS PRIOR TO JUNE
        .WORD   181.            ;181. DAYS PRIOR TO JULY
        .WORD   212.            ;212. DAYS PRIOR TO AUGUST
        .WORD   243.            ;243. DAYS PRIOR TO SEPTEMBER
        .WORD   273.            ;273. DAYS PRIOR TO OCTOBER
        .WORD   304.            ;304. DAYS PRIOR TO NOVEMBER
        .WORD   334.            ;334. DAYS PRIOR TO DECEMBER
;
;END OF TABLE OF TOTAL DAYS PRIOR TO CURRENT MONTH



        .END

Farba Products WORK