setala icon

VAX/VMS Macro-32 TERVEHDYS.MAR

setala | PRO | 06/08/26 08:37:40 AM UTC (Edited) | 0 ⭐ | 3172 👁️ | Never ⏰ | [#VAX #GPT-5.5]
text |

7.9 KB

|

Source Code

|

0 👍

/

0 👎

        .TITLE  TERVEHDYS
        .IDENT  /V1.4/
         .LIBRARY /SYS$LIBRARY:STARLET.MLB/
         $SSDEF
        $DSCDEF
         .PSECT  DATA,NOEXE,WRT,LONG
 UTC_TIME:       .BLKQ   1
UTCNUM:         .BLKW   7
FINNUM:         .BLKW   7
 DAY:            .BLKL   1
YEAR:           .BLKL   1
HOUR:           .BLKL   1
MINUTE:         .BLKL   1
SECOND:         .BLKL   1
 MAR_LAST:       .BLKL   1
OCT_LAST:       .BLKL   1
MONTH_PTR:      .BLKL   1
OFFSET_HOURS:   .BLKL   1
MONTH_LEN:      .BLKL   1
 OUTBUF:         .BLKB   132
OUTLEN:         .BLKW   1
 OUT_DSC:
        .WORD   132
        .BYTE   DSC$K_DTYPE_T
        .BYTE   DSC$K_CLASS_S
        .ADDRESS OUTBUF
 FMT_DATE:       .ASCID  /!UL. !AS !UL !2ZL:!2ZL:!2ZL Suomen aikaa/
 MON01:          .ASCID  /tammikuuta/
MON02:          .ASCID  /helmikuuta/
MON03:          .ASCID  /maaliskuuta/
MON04:          .ASCID  /huhtikuuta/
MON05:          .ASCID  /toukokuuta/
MON06:          .ASCID  /kesakuuta/
MON07:          .ASCID  /heinakuuta/
MON08:          .ASCID  /elokuuta/
MON09:          .ASCID  /syyskuuta/
MON10:          .ASCID  /lokakuuta/
MON11:          .ASCID  /marraskuuta/
MON12:          .ASCID  /joulukuuta/
 MONTH_TABLE:
        .ADDRESS MON01,MON02,MON03,MON04,MON05,MON06
        .ADDRESS MON07,MON08,MON09,MON10,MON11,MON12
 MDAYS:
        .LONG   31,28,31,30,31,30,31,31,30,31,30,31
 MSG_TIME:       .ASCID  /Paivamaara ja aika:/
GREET_MORN:     .ASCID  /Hyvaa huomenta!/
GREET_DAY:      .ASCID  /Hyvaa paivaa!/
GREET_EVE:      .ASCID  /Hyvaa iltaa!/
GREET_NIGHT:    .ASCID  /Hyvaa yota!/
         .PSECT  CODE,EXE,NOWRT,LONG
         .ENTRY  START,^M<>
         $GETTIM_S TIMADR=UTC_TIME
        BLBS    R0,10$
        JMP     ERROR
10$:
        $NUMTIM_S TIMBUF=UTCNUM,TIMADR=UTC_TIME
        BLBS    R0,20$
        JMP     ERROR
20$:
         ; Find last Sunday of March and October in the UTC year.
        MOVZWL  UTCNUM+0,R0
        MOVL    #3,R1
        MOVL    #31,R2
        BSBW    LAST_SUNDAY
        MOVL    R0,MAR_LAST
         MOVZWL  UTCNUM+0,R0
        MOVL    #10,R1
        MOVL    #31,R2
        BSBW    LAST_SUNDAY
        MOVL    R0,OCT_LAST
         ; Default: Finnish winter time, UTC+2.
        MOVL    #2,OFFSET_HOURS
         ; Finnish summer time: last Sunday of March 01:00 UTC
        ; through last Sunday of October before 01:00 UTC.
        MOVZWL  UTCNUM+2,R0          ; UTC month
         CMPL    R0,#3
        BLSS    HAVE_OFFSET          ; Jan-Feb
         CMPL    R0,#10
        BGTR    HAVE_OFFSET          ; Nov-Dec
         CMPL    R0,#3
        BEQL    CHECK_MARCH
         CMPL    R0,#10
        BEQL    CHECK_OCTOBER
         MOVL    #3,OFFSET_HOURS     ; Apr-Sep
        BRW     HAVE_OFFSET
 CHECK_MARCH:
        MOVZWL  UTCNUM+4,R0          ; UTC day
        CMPL    R0,MAR_LAST
        BLSS    HAVE_OFFSET
        BGTR    MARCH_DST
         MOVZWL  UTCNUM+6,R0          ; UTC hour
        CMPL    R0,#1
        BLSS    HAVE_OFFSET
 MARCH_DST:
        MOVL    #3,OFFSET_HOURS
        BRW     HAVE_OFFSET
 CHECK_OCTOBER:
        MOVL    #3,OFFSET_HOURS     ; October is DST until cutoff
        MOVZWL  UTCNUM+4,R0
        CMPL    R0,OCT_LAST
        BLSS    HAVE_OFFSET
        BGTR    OCT_STD
         MOVZWL  UTCNUM+6,R0
        CMPL    R0,#1
        BLSS    HAVE_OFFSET
 OCT_STD:
        MOVL    #2,OFFSET_HOURS
 HAVE_OFFSET:
        ; Copy UTC numeric time to FINNUM.
        MOVW    UTCNUM+0,FINNUM+0
        MOVW    UTCNUM+2,FINNUM+2
        MOVW    UTCNUM+4,FINNUM+4
        MOVW    UTCNUM+6,FINNUM+6
        MOVW    UTCNUM+8,FINNUM+8
        MOVW    UTCNUM+10,FINNUM+10
        MOVW    UTCNUM+12,FINNUM+12
         ; Add 2 or 3 hours.
        MOVZWL  FINNUM+6,R0
        ADDL2   OFFSET_HOURS,R0
        CMPL    R0,#24
        BLSS    STORE_HOUR
         SUBL2   #24,R0
        MOVW    R0,FINNUM+6
        BSBW    INC_DATE
        BRW     AFTER_HOUR
 STORE_HOUR:
        MOVW    R0,FINNUM+6
 AFTER_HOUR:
        MOVZWL  FINNUM+0,YEAR
        MOVZWL  FINNUM+4,DAY
        MOVZWL  FINNUM+6,HOUR
        MOVZWL  FINNUM+8,MINUTE
        MOVZWL  FINNUM+10,SECOND
         MOVZWL  FINNUM+2,R1
        DECL    R1
        MULL2   #4,R1
        MOVL    MONTH_TABLE(R1),MONTH_PTR
         PUSHL   SECOND
        PUSHL   MINUTE
        PUSHL   HOUR
        PUSHL   YEAR
        PUSHL   MONTH_PTR
        PUSHL   DAY
        PUSHAQ  OUT_DSC
        PUSHAL  OUTLEN
        PUSHAQ  FMT_DATE
        CALLS   #9,G^LIB$SYS_FAO
        BLBS    R0,30$
        JMP     ERROR
30$:
        MOVW    OUTLEN,OUT_DSC
         PUSHAQ  MSG_TIME
        CALLS   #1,G^LIB$PUT_OUTPUT
         PUSHAQ  OUT_DSC
        CALLS   #1,G^LIB$PUT_OUTPUT
         CMPW    FINNUM+6,#6
        BLSS    SAY_NIGHT
         CMPW    FINNUM+6,#12
        BLSS    SAY_MORN
         CMPW    FINNUM+6,#18
        BLSS    SAY_DAY
         CMPW    FINNUM+6,#22
        BLSS    SAY_EVE
 SAY_NIGHT:
        PUSHAQ  GREET_NIGHT
        BRB     PRINT_GREET
 SAY_MORN:
        PUSHAQ  GREET_MORN
        BRB     PRINT_GREET
 SAY_DAY:
        PUSHAQ  GREET_DAY
        BRB     PRINT_GREET
 SAY_EVE:
        PUSHAQ  GREET_EVE
 PRINT_GREET:
        CALLS   #1,G^LIB$PUT_OUTPUT
        MOVL    #SS$_NORMAL,R0
        RET
 ERROR:
        PUSHL   R0
        CALLS   #1,G^LIB$STOP
        RET
 ; Increment FINNUM date by one day.
 INC_DATE:
        MOVZWL  FINNUM+0,R0          ; year
        MOVZWL  FINNUM+2,R1          ; month
        BSBW    GET_MONTH_LENGTH
        MOVL    R0,MONTH_LEN
         MOVZWL  FINNUM+4,R0          ; day
        INCL    R0
        CMPL    R0,MONTH_LEN
        BGTR    NEXT_MONTH
         MOVW    R0,FINNUM+4
        RSB
 NEXT_MONTH:
        MOVW    #1,FINNUM+4
         MOVZWL  FINNUM+2,R0
        INCL    R0
        CMPL    R0,#12
        BGTR    NEXT_YEAR
         MOVW    R0,FINNUM+2
        RSB
 NEXT_YEAR:
        MOVW    #1,FINNUM+2
        MOVZWL  FINNUM+0,R0
        INCL    R0
        MOVW    R0,FINNUM+0
        RSB
 ; Input:
;   R0 = year
;   R1 = month
; Output:
;   R0 = length of month
 GET_MONTH_LENGTH:
        DECL    R1
        MULL2   #4,R1
        MOVL    MDAYS(R1),R2
         ; February: check leap year.
        CMPL    R1,#4                ; original month 2 -> index 1 -> offset 4
        BNEQ    MONTH_LEN_DONE
         BSBW    IS_LEAP
        TSTL    R0
        BEQL    MONTH_LEN_DONE
        MOVL    #29,R2
 MONTH_LEN_DONE:
        MOVL    R2,R0
        RSB
 ; Input:
;   R0 = year
; Output:
;   R0 = 1 if leap year, 0 otherwise
 IS_LEAP:
        MOVL    R0,R3
         MOVL    R3,R4
        DIVL2   #400,R4
        MULL2   #400,R4
        CMPL    R3,R4
        BEQL    LEAP_YES
         MOVL    R3,R4
        DIVL2   #100,R4
        MULL2   #100,R4
        CMPL    R3,R4
        BEQL    LEAP_NO
         MOVL    R3,R4
        DIVL2   #4,R4
        MULL2   #4,R4
        CMPL    R3,R4
        BEQL    LEAP_YES
 LEAP_NO:
        CLRL    R0
        RSB
 LEAP_YES:
        MOVL    #1,R0
        RSB
 ; Input:
;   R0 = year
;   R1 = month, 3 or 10
;   R2 = last day of month
; Output:
;   R0 = day number of last Sunday in that month
 LAST_SUNDAY:
        MOVL    R0,R3
        MOVL    R1,R4
        MOVL    R2,R5
         ADDL3   #1,R4,R6
        MULL2   #13,R6
        DIVL2   #5,R6
         ADDL3   R5,R6,R7
        ADDL2   R3,R7
         MOVL    R3,R8
        DIVL2   #4,R8
        ADDL2   R8,R7
         MOVL    R3,R8
        DIVL2   #100,R8
        SUBL2   R8,R7
         MOVL    R3,R8
        DIVL2   #400,R8
        ADDL2   R8,R7
         MOVL    R7,R8
        DIVL2   #7,R8
        MULL2   #7,R8
        SUBL2   R8,R7
         ADDL2   #6,R7
        MOVL    R7,R8
        DIVL2   #7,R8
        MULL2   #7,R8
        SUBL2   R8,R7
         SUBL3   R7,R5,R0
        RSB
         .END    START
 

Comments